建立對象一般僅僅是一個new關鍵詞而已。程序員
虛擬機在建立對象以前須要先判斷是否已經被加載,經過檢查這個指令的參數是否能在常量池中定位到一個類的符號引用,而且檢查這個符號引用表明的類是否已被加載、解析和初始化過。若是沒有,那必須先執行相應的類的加載過程。算法
對象所需內存的大小在類加載完成後便徹底肯定,爲對象分配空間的任務等同於把一塊肯定大小的內存從Java堆中劃分出來。緩存
根據Java堆中的內存是否規整有兩種內存的分配方式指針碰撞方式和空閒列表方式,Java堆是否規整由所採用的垃圾收集器是否帶有壓縮整理功能決定。安全
對象在虛擬機中建立時很是頻繁的行爲,即便是僅僅修改一個指針指向的位置,在併發狀況下也並非線程安全的,可能出現正在給對象A分配內存,指針還沒來得及修改,對象B又同時使用了原來的指針來分配內存的狀況。解決這個問題有兩種方案,一種是同步處理另外一種是本地線程分配緩存。併發
虛擬機將分配到的內存空間都初始化爲零值(不包括對象頭),若是使用了TLAB,這一工做過程也能夠提早至TLAB分配時進行。內存空間初始化保證了對象的實例字段在Java代碼中能夠不賦初始值就直接使用,程序能訪問到這些字段的數據類型所對應的零值。 spa
虛擬機對對象進行必要的設置,例如這個對象是哪一個類的實例、如何才能找到類的元數據信息、對象的哈希碼、對象的GC分代年齡等信息。這些信息存放在對象的對象頭之中。線程
在上面的工做都完成以後,從虛擬機的角度看,一個新的對象已經產生了。可是從Java程序的角度看,對象的建立纔剛剛開始<init>方法尚未執行,全部的字段都仍是零。因此,通常來講(由字節碼中是否跟隨invokespecial指令所決定),執行new指令以後會接着執行<init>方法,把對象按照程序員的意願進行初始化,這樣一個真正可用的對象纔算產生出來。指針