Java虛擬機new對象

類加載檢查
java虛擬機在遇到一條 new 指令時,首先會檢查是否能在常量池中定位到這個類的符號引用,而且是否已被加載過、解析和初始化過。若是沒有,那必須先執行類加載過程java

類加載的相關知識可參考:JVM的類加載機制算法

分配內存
在類加載檢查經過後,接下來虛擬機將爲新生對象分配內存。併發

分配方式有 指針碰撞 和 空閒列表 兩種線程

指針碰撞:Java堆中的內存是規整的,全部用過的內存都放在一邊,空閒的內存放在另外一邊,中間放着一個指針做爲分界點的指示器,分配內存也就是把指針向空閒空間那邊移動一段與內存大小相等的距離。指針

空閒列表:Java堆中的內存不是規整的,已使用的內存和空閒的內存相互交錯,就沒有辦法簡單的進行指針碰撞了。虛擬機必須維護一張列表,記錄哪些內存塊是可用的,在分配的時候從列表中找到一塊足夠大的空間劃分給對象實例,並更新列表上的記錄對象

Java 堆內存是否規整,取決於 GC 的垃圾回收算法,在JVM中標記壓縮、複製算法的內存是規整的、而標記清除則是不規整的內存

垃圾回收算法相關知識可參考:JVM垃圾收集算法詳解虛擬機

內存分配併發問題
CAS操做:CAS是屬於原子性操做,更多關於此內容可參考此內容:Java原子類操做原理剖析原理

TLAB: 爲每個線程預先在Eden區分配一起內存,JVM在給線程中的對象分配內存時,首先在TLAB分配,當對象大於TLAB中的剩餘內存或TLAB的內存已用盡時,再採用上述的CAS進行內存分配垃圾回收

內存空間初始化
內存分配完成後,虛擬機須要將分配到的內存空間都初始化爲零值。這一步操做保證了對象的實例字段在 Java 代碼中能夠不賦初始值就直接使用,程序能訪問到這些字段的數據類型所對應的零值。例如:


int a=1
long b=2
實際上在這時被賦值爲了
a=0
b=0L
設置對象頭
內存空間初始化完成以後,虛擬機要在對象頭中保存如下必要的信息:

這個對象是那個類的實例

如何才能找到類的元數據信息

對象的哈希碼

對象的 GC 分代年齡

等等

執行構造方法這裏纔是咱們最熟悉的地方

相關文章
相關標籤/搜索