在HotSpot虛擬機中,對象在內存中存儲的布局可以分為3塊區域:
- 對象頭(Header)
- 實例數據(Instance Data)
- 對齊填充(Padding)
對象頭
HotSpot虛擬機的對象頭包括兩部分信息:
- 運行時數據:用于存儲對象自身的運行時數據,如HashCode、GC分代年齡、鎖狀態標志、線程持有的鎖、 偏向線程ID、偏向時間戳等
- 類型指針: 即對象指向它的類元數據的指針,虛擬機通過這個指針來確定這個對象是哪個類的實例;當然,查找對象的元數據信息并不一定要通過對象本身,并不是所有的虛擬機實現都必須在對象數據上保留類型指針
如果對象是Java數組,那在對象頭中還必須有一塊用于標記數組長度的數據,因為虛擬機可以通過普通對象的
元數據確定對象的大小,但是從數組的元數據中卻無法確定數組的大小。
實例數據
實例數據部分是對象真正存儲的有效信息,也是在程序代碼中所定義的各種類型的字段內容。父類和子類中定義的會被記錄下來,存儲順序受虛擬機分配策略和字段在Java源碼中定義的順序影響。
HotSpot虛擬機默認的分配策略為 longs/doubles, ints, shorts/chars, bytes/booleans, oops(
Ordinary Object Pointers),從分配策略上可以看出,相同寬度的字段總是被分配到一起。
對齊填充
它起著占位符的作用。因為HotSpot VM的自動內存管理系統要求對象的起始地址必須是8字節的整數倍,對象頭部正好是8字節的整數倍,因此,當對象實例數據部分沒有對齊時,就需要通過對齊填充來補全。