JVM物件建立流程解析
阿新 • • 發佈:2018-11-05
Person p = new Person();
這是一個簡單的建立物件語句,讓我們來看看java虛擬機器是如何實現它的:
1.類載入檢查
jvm遇到一條new指令時,首先將去檢查這個指令的引數是否能在常量池中定位到一個類的符號引用,並且檢查這個符號引用代表的類是否已經被載入、解析和初始化過,如果沒有則進行相應的類載入過程。
2.jvm分配記憶體
java程式在執行時,虛擬機器會在記憶體中申請一塊記憶體空間用來執行jvm:
在這塊jvm記憶體區域中,有兩塊區域,堆和棧,如圖:
我們寫的類,如Person這個類,類的名字,有什麼成員變數什麼成員方法等資訊,都儲存在棧中輸入Person類的區域,相當於一個類的模板,如圖:
而我們真正通過Person p = new Person();去new一個類的時候,也就是例項化這個類的時候,例項物件儲存的空間是在堆中,只不過我們在棧中儲存了這個例項物件的名字還有一些別的資訊,但是等到去拿這個物件所儲存的資料等東西的時候,還是要去堆中尋找:
jvm建立物件的第二步就是劃分這塊空間的,劃分空間還有講究,有兩種方式,第一種是如果java堆是連續分配的,那麼我們在已經分配給例項物件的堆空間和還在空著未分配給例項物件的堆空間之間有一個分界線,我們用指標來指向這個位置,如圖:
當我們下一次建立物件在堆空間中為它分配空間的時候,直接將指標向未利用的空間移動出這個新物件的大小就可以了,如圖:
這種方式叫做“指標碰撞”
另一種方式就比較好理解了,jvm使用一個列表來記錄已利用的堆空間和未利用的堆空間,每次給新物件分配堆空間的時候,都會更新列表中的記錄,這種方式叫做“空閒列表”
3.設定物件基本資訊
物件分配到空間之後,JVM會將分配到的記憶體空間都初始化為零值(不包括物件頭),虛擬機器要對物件進行必要的基本資訊設定。如該物件是哪個類的例項、如果找到類的元資料資訊、物件的雜湊碼、物件的GC分代年齡等資訊。這些資訊存放在物件的物件頭中,被叫做“Mark Word”,這一部分資訊存放在我們剛才所說的棧中用來存放例項物件資訊的空間中。
4.初始化物件和呼叫建構函式
直到這一步,我們才真正按照程式碼編寫者的意願,對物件進行初始化操作,如:對物件中的成員變數賦初值,呼叫建構函式等操作,到次位置一個物件才算是完成了建立和初始化的操作,可以使用了。