前言
在HotSpot虛擬機中,對象在內存中存儲的佈局分爲3塊區域:
- 對象頭
- 實例數據
- 對其填充
對象頭
對象頭中包括兩部分信息:
-
第一部分用於存儲對象自身的運行時數據,長度爲32位或64位:
- 哈希碼
- GC分代年齡
- 鎖狀態標誌
- 線程持有的鎖
- 偏向線程ID
- 偏向時間戳
因爲對象頭佔用的空間比較小,所以空間不是固定的數據結構,是隨着狀態不同,而存儲的內容不同:
存儲內容 標誌位 狀態 指向棧中鎖記錄的指針 00 輕量級鎖 對象哈希碼、對象分代年齡 01 未鎖定 偏向線程ID、偏向時間戳、對象分代年齡 01 可偏向鎖 指向重量級鎖的指針 10 重量級鎖 空,不需要記錄信息 11 GC標記 -
第二部分是類型指針,
- 就是對象指向它的類元數據的指針。
- 如果對象是Java數組,在對象頭中還必須有一塊用於記錄數組長度的數據。
- 因爲數組的元數據中無法確定數組的大小。但是虛擬機可以通過普通Java對象的元數據信息確定Java對象的大小。
實例數據
存儲對象的有效信息,也就是在代碼中定義的各種類型的字段。
無論是從父類繼承下來的,還是在子類中定義的字段。
相同寬度的字段總是被分配到一起。
在滿足這個前提的條件下,在父類中定義的變量會出現在子類之前。
當CompactFields參數值爲true,那麼子類之中較窄的變量也可能會插入到父類變量的空隙之中。
對齊填充
對齊填充不是必然存在的,僅僅起着佔位符的作用。
HotSpot的自動內存管理系統要求對象的起始地址必須是8字節的整數倍。