首先JVM遇到new指令,會檢查指令參數可否在常量池中定位到一個符號引用。而且檢查這個符號引用所表明的類是否已被加載、解析和初始化過。若是沒有會進行相應的類加載過程。佈局
類加載驗證經過後,爲新生對象分配內存。spa
內存分配完成後,JVM須要將分配到的內存空間都初始化爲零。這一步操做保證了對象的實例字段在Java代碼中能夠不賦初始值就直接使用。線程
對對象進行必要的設置,例如這個對象是哪一個類的實例,如何才能找到類的元數據信息,對象的Hash碼值,對象的GC分代年齡等信息。這些信息都放在對象頭中,grn指針
上述工做完成後,對虛擬機而言一個新的對象已經產生。從Java程序而言對象的建立剛剛開始。根據當前虛擬機運行狀態的不一樣,如是否啓用偏向鎖等,對象頭都會有不一樣的設置。對象
在HotSpot中,對象在內存中的佈局分爲3塊區域:繼承
包含兩部分數據:內存
用於存儲對象自身運行時數據,如Hash碼、GC分帶年齡、鎖狀態標誌、線程持有的鎖等源碼
另一部分是類型指針,即對象指向它的類元數據指針,經過這個指針肯定對象是哪一個類的實例。(並非全部的虛擬機都在對象數據上保留類型指針)虛擬機
是對象真正存儲的有效信息,也就是程序代碼中所定義的各類類型的字段內容。不管父類繼承仍是子類定義都要記錄,這部分數據受虛擬機分配策略參數和Java在源碼中的定義順序影響。內存管理
僅僅起着佔位符的做用,並非必要的,也無心義。(例如Hot Spot自動內存管理系統要求對象起始地址必須是8字節的證書倍,須要對齊填充來補全)
Java程序須要經過棧上的reference數據來訪問堆中的具體對象,reference類型在JVM中只規定了一個指向對象的引用,並無定義這個引用經過何種方式去定位,訪問堆中對象的具體位置。對象的訪問方式取決於JVM的實現方式。
主流方式:
使用句柄
Java堆會劃分一塊內存做爲句柄池,reference中存儲的是句柄地址,而句柄中包含了對象的實例數據和類型數據的具體地址信息。
直接訪問
reference存儲的直接就是對象地址。
優缺點:
使用句柄最大的好處是reference中存儲的是穩定的句柄地址,在對象被移動時只改變du句柄中的實例數據指針,而reference不須要修改。
使用直接地址最大的好處是速度更快,節省了一次指針的定位開銷。