JVM-物件建立、訪問、記憶體佈局
-
Java的物件建立
虛擬機器遇到一條新的指令時,首先將去檢查這個指令的引數是否能在常量池中定位到一個類的符號,並且檢查這個符號引用代表的類是已被載入,解析和初始化過,如果沒有先執行相應的類載入過程。
在類載入檢查通過後,為新生物件分配記憶體。物件所需記憶體的大小在類載入完成後便可以完全確定,為物件分配空間的任務等同於把一塊確定大小的記憶體從java的堆中劃分出來。
1.指標碰撞
假設Java的記憶體絕對規整,所有已使用的記憶體在一遍,另一邊是未使用的,中交放一個指標作為分界點的指示器,那所分配記憶體就僅僅指標向空閒那邊挪到一段與物件大小相等的距離,圖中虛線位置,這種方式稱為“指標碰撞”。
2.空閒列表
如果Java的堆中的記憶體並不是規整的,已使用的和未使用的互相交錯,沒有辦法進行簡單的指標碰撞,虛擬機器就必須維護一個表,記錄哪些記憶體塊是可以用的,並且找一個足夠大的記憶體空間分配例項物件;並更新列表裡面的記錄,這種分配方式稱為“空閒列表”。
選擇哪種分配方式由Java的堆是否規整決定,二Java的堆是否規整由所採用的垃圾收集器決定。
-
物件記憶體佈局
1.物件頭
第一部分:儲存物件自身的執行時資料,如雜湊碼,GC分代年齡,鎖狀態標誌,執行緒持有的鎖,偏向執行緒ID,偏向時間戳等。
另一部分:型別指標,即物件指向它的元資料指標,虛擬機器通過這個指標來確定這個物件是哪個類的例項如果物件是一個數組,那在物件頭中還必須有一塊用於記錄陣列長度。的資料。
2.實時資料
物件真正儲存的有效資訊,也是在程式程式碼中所定義的各種型別的欄位內容。
3.對齊填充
佔位符作用,hotSpot VM的自動記憶體管理系統要求物件的大小必須是8位元組的整數倍。二物件頭部分正好是8位元組的倍數,當例項資料部分沒有對齊時。就需要通過對齊填充來補全。
-
物件訪問定位
Java的程式通過棧上的引用資料來操作堆上的具體物件。
目前主流的訪問方式有使用控制代碼和直接指標兩種。
1.控制代碼
如果使用控制代碼訪問的話,那麼java的堆中將會劃分出一塊記憶體來作為控制代碼池,參考中儲存的就是對物件的控制代碼地址,而控制代碼中包含了物件例項資料與型別資料各種的具體地址資訊。使用控制代碼的最大好處就是參考中儲存的是文件的控制代碼地址,在物件移動的時候只會改變控制代碼中示例資料指標,而本身不需要修改。
2.直接指標
如果使用直接指標,參考中儲存的直接就是物件地址,最大好處就是速度快,節省了一次指標定位的時間開銷.Sun hotSpot使用的是直接指標。