Java對象在JVM中的內存佈局 — JVM系列(三)

前言

在HotSpot虛擬機中,對象在內存中存儲的佈局分爲3塊區域:

  1. 對象頭
  2. 實例數據
  3. 對其填充

對象頭

對象頭中包括兩部分信息:

  1. 第一部分用於存儲對象自身的運行時數據,長度爲32位或64位:

    1. 哈希碼
    2. GC分代年齡
    3. 鎖狀態標誌
    4. 線程持有的鎖
    5. 偏向線程ID
    6. 偏向時間戳

    因爲對象頭佔用的空間比較小,所以空間不是固定的數據結構,是隨着狀態不同,而存儲的內容不同:

    存儲內容 標誌位 狀態
    指向棧中鎖記錄的指針 00 輕量級鎖
    對象哈希碼、對象分代年齡 01 未鎖定
    偏向線程ID、偏向時間戳、對象分代年齡 01 可偏向鎖
    指向重量級鎖的指針 10 重量級鎖
    空,不需要記錄信息 11 GC標記
  2. 第二部分是類型指針

  • 就是對象指向它的類元數據的指針。
  • 如果對象是Java數組,在對象頭中還必須有一塊用於記錄數組長度的數據
  • 因爲數組的元數據中無法確定數組的大小。但是虛擬機可以通過普通Java對象的元數據信息確定Java對象的大小。

實例數據

存儲對象的有效信息,也就是在代碼中定義的各種類型的字段。

無論是從父類繼承下來的,還是在子類中定義的字段。

相同寬度的字段總是被分配到一起。

在滿足這個前提的條件下,在父類中定義的變量會出現在子類之前。

當CompactFields參數值爲true,那麼子類之中較窄的變量也可能會插入到父類變量的空隙之中。

對齊填充

對齊填充不是必然存在的,僅僅起着佔位符的作用。

HotSpot的自動內存管理系統要求對象的起始地址必須是8字節的整數倍。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章