虛擬機對象的訪問定位和內存佈局

Java程序需要通過棧上的reference數據來操作堆上的具體對象。
由於reference類型在Java虛擬機規範中之規定了一個指向對象的引用,並沒有定義這個引用應該通過何種方式去定位訪問隊中的對象的具體位置,所以對象的訪問方式也是由虛擬機實現而定的。
目前主流方式是使用句柄和直接指針兩種。
在這裏插入圖片描述
通過句柄訪問的話,Java堆中將會劃分出一塊內存作爲句柄池,reference中存儲的就是對象的句柄地址,而句柄中包含了對象實例數據與類型數據各自的具體地址信息。
在這裏插入圖片描述
如果是指針直接訪問,那麼Java堆對象的佈局中就必須考慮如何放置訪問類型數據的相關信息,而reference中存儲的直接就是對象地址。
兩種方式的優勢:
句柄訪問最大好處就是reference中存儲的是穩定的句柄地址,在對象被移動時只會改變句柄中的實例數據指針,而reference本身不需要修改。
直接指針訪問方式最大好處就是速度更快,節省了一次指針定位的時間開銷,由於對於下部分的訪問在Java中非常頻繁,因此此類開銷積少成多後也是一項非常可觀的執行成本。

HotSpot虛擬機中,對象在內存中存儲的佈局分爲三塊區域:對象頭(Header)、實例數據(Instance Data)和對其填充(Padding)。

對象頭包含兩部分信息:
第一部分用於存儲對象自身的運行時數據。
第二部分是類型指針,即對象指向它的類元數據的指針,虛擬機通過這個指針來確定這個對象是哪個類的實例。

用於存儲對象自身的運行時數據,例如:哈希碼(hashcode)、GC分代年齡、鎖狀態標誌、線程持有的鎖、偏向線程ID、偏向時間戳等,這部分官方稱爲Mark Word。

並不是所有的虛擬機實現都必須在對象數據上保留類型指針,查找對象的元數據信息並不一定要經過對象本身。

另外對象是一個Java數組,那對象頭中還必須有一塊記錄數組長度的數據。

對其填充並不是必然存在的,也沒有特殊的意義,僅僅是用於佔位符的作用。

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