標籤:虛擬 分配 java對象 book 分代 指令 類載入 交流 關鍵字
以Hotspot虛擬機器為例,描述對象的 建立過程。
對象的建立
通過new關鍵字建立對象
- 虛擬機器在遇到new關鍵字後先去常量池中尋找一個類的符號引用,
- 檢查這個類是否被載入,解析和初始化,如果沒有則執行類載入過程
- 為對象分配記憶體
在類載入過程完成後類就已經確定了對象所需要的大小,然後從堆中劃分出確定大小的一塊記憶體
- 虛擬機器初始化對象零值
記憶體配置完成後,會對分配的記憶體空間進行零值初始化,保證java對象執行個體欄位在java代碼中可以不賦初始值就直接使用,程式可以訪問到這些零值。
- 設定對象頭資訊
例如對象是哪個類的執行個體,如何找到類類資訊,hash碼,GC分代年齡等。
java程式初始化對象
經曆完上面過程,虛擬機器層面看一個對象已經建立完成,但java程式層面的對象建立才剛剛開始。虛擬機器執行完new指令後會接著執行
對象記憶體布局對象的記憶體布局分為三個地區
- 對象頭
儲存物件自身的運行時資料:比如HashCode,GC分代年齡,鎖狀態標誌,線程持有的鎖,偏向線程ID,偏向時間戳記等
儲存類型指標:對象指向它的類別中繼資料的類型指標,虛擬機器通過這個指標來確定這個對象是哪個類的執行個體(這不是必須的)。
- 執行個體資料
執行個體資料是對象真正儲存的有效資訊,也就是在程式碼中定義的各種類型的欄位內容。
對其填充
不是必然存在的,沒有特別的含義,僅起著預留位置的作用。
對象的訪問定位java程式通過棧(Heap)上reference(引用)資料來操作堆上的具體對象。
目前訪問對象的兩種方式為控制代碼和直接指標兩種
通過控制代碼訪問
java堆會划出一塊記憶體來作為控制代碼池,reference中儲存的就是對象的控制代碼地址,而控制代碼地址中包含了對象執行個體資料與類型資料各自的具體地址資訊。如:
直接指標訪問
reference中直接儲存物件地址,如:
兩種訪問方式的對比
控制代碼訪問:儲存的是穩定的控制代碼地址,對象改變時僅改變控制代碼的執行個體資料指標,而reference本身不需要修改
直接指標:最大的好處是訪問速度更快,節約了一次指標定位時間的開銷(Hotspot使用這種方式)
關注公眾號一起讀書學習交流
(二)jvm-Java對象的建立、訪問