【JVM】一個Java對象的創建過程

Object obj = new Object();
Java中創建對象時,需要經過5個階段,分別是:類加載檢查、分配內存、初始化零值、設置對象頭、執行init方法。

1、類加載檢查

當JVM執行到一條new指令時,先檢查這條指令的參數是否能在常量池定位到這個類的符號引用,同時檢查這個類是否已被加載、解析、初始化,如果沒有則會先進行類加載過程。

2、分配內存

在類加載檢查後,JVM爲新對象分配內存。對象所需的內存大小在類加載完成後可確定,因此分配內存的過程就是把一塊確定大小的內存從堆中劃分出來。分配方式有指針碰撞和空閒列表兩種,選擇哪種分配方式由堆內存是否規整決定,堆內存是否規整又由垃圾收集器決定。
指針碰撞:適用於堆內存規整的情況,由於堆中將已被使用過的內存整合到一邊,未使用的內存整合到另一邊,中間有一個分界指針,所以分配內存時只需向未分配內存的方向移動對象所佔內存大小位置即可。針對標記-整理算法的垃圾收集器。
空閒列表:適用於堆內存不規整的情況,JVM會維護一個列表,列表中記錄哪些內存塊可用。分配內存時,找到一塊足夠大的內存塊來分配給新對象,然後更新列表。針對標記-清除算法的垃圾收集器。
那麼內存分配的併發問題如何解決?
JVM通過兩種方式保證內存分配的安全性:
CAS:在分配內存時,JVM會採用CAS+失敗重試的方式保證更新操作的原子性
TLAB:給每個線程都先在Eden區分配一塊私有內存區域,JVM在給線程中對象分配內存時,先在TLAB分配,當對象大於TLAB的剩餘內存或TLAB內存用盡時,再採用CAS的方式在共享內存上分配。

3、初始化零值

內存分配完成後,JVM要將分配的內存空間初始化爲零值,這一步也保證了對象的實例字段能不賦初始值就直接使用,程序訪問到的是這些字段對應數據類型的零值。

4、設置對象頭

初始化零值後,JVM會設置對象的對象頭信息,包括:Mark Word和類型指針。Mark Word包含對象的哈希碼、GC分代年齡、鎖信息等,類型指針指向方法區中類的元數據信息。

5、執行init方法

按照代碼中指定的初始化方法對對象進行初始化。

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