虛擬機(jī)遇到一條new指令時(shí),首先將去檢查這個(gè)指令的參數(shù)是否能在常量池中定位到一個(gè)類的符號(hào)引用,并且檢查這個(gè)符號(hào)引用代表的類是否已被加載、解析和初始化過(guò)。
虛擬機(jī)將為新生對(duì)象分配內(nèi)存,內(nèi)存分配方式有兩種
指針碰撞:假設(shè)Java堆中內(nèi)存是絕對(duì)規(guī)整的,所有用過(guò)的內(nèi)存都放在一邊,空閑的放在另一邊,中間放著一個(gè)指針作為分界點(diǎn)的指示器,那所分配內(nèi)存就僅僅是把那個(gè)指針向空閑空間那邊挪動(dòng)一段與對(duì)象大小相等的距離。
空閑列表:如果Java堆中的內(nèi)存并不是規(guī)整的,已使用的內(nèi)存和空閑的內(nèi)存相互交錯(cuò),虛擬機(jī)就必須維護(hù)一個(gè)列表,記錄哪些內(nèi)存塊是可用的,在分配的時(shí)候從列表中找到一塊足夠大的空間劃分給對(duì)象實(shí)例,并更新列表上的記錄。
對(duì)象創(chuàng)建線程安全問(wèn)題解決方案有兩種:
1、對(duì)分配內(nèi)存空間的動(dòng)作進(jìn)行同步處理
2、每個(gè)線程在Java堆中預(yù)先分配一小塊內(nèi)存,成為本地線程分配緩沖(Thread Local Allocation Buffer,TLAB)。
內(nèi)存分配完成后,虛擬機(jī)需要將分配到的內(nèi)存空間都初始化為零值(不包括對(duì)象頭)。
虛擬機(jī)對(duì)對(duì)象進(jìn)行必要的設(shè)置,如這個(gè)對(duì)象是哪個(gè)類的實(shí)例、如何找到類的元數(shù)據(jù)信息、對(duì)象的哈希碼、對(duì)象的GC分代年齡等信息(存放于對(duì)象頭)。
執(zhí)行在<init>方法,把對(duì)象按照程序員的意愿進(jìn)行初始化。