對象的建立大體過程:java
虛擬機遇到一條new指令時,首先會檢查這個指令的參數是否能在常量池中定位到一個類的符號引用,而且檢查這個符號引用表明的類是否已經被加載、解析和初始化過。若是沒有,則必須先執行相應的加載過程。數組
在類加載檢查經過之後,接下來將爲新生對象分配內存。對象所需內存的大小在類加載完成後即可徹底肯定。爲對象分配空間的任務等同於把一塊肯定大小的內存從Java堆中劃分出來。爲對象分配空間的任務等同於把一塊肯定大小的內存從Java堆中劃分出來。分配方式:指針碰撞、空閒列表。選擇哪一種分配方式由Java堆是否規整決定,而java堆是否規整又由所採用的垃圾收集器是否帶有壓縮整理功能決定。 另外還須要考慮的問題是對象建立在虛擬機中是不是很是頻繁的行爲,即便是僅僅修改一個指針所指向的位置,在併發狀況下也不是線程安全的。有兩種解決方案:一、對分配內存空間的動做進行同步處理 二、把內存分配的動做按照線程劃分在不一樣的空間中進行。安全
在內存分配完成後,虛擬機須要將分配到的內存空間都初始化爲零值(不包括對象頭)併發
接下來,虛擬機要對對象進行必要的設置,如這個對象時哪一個類的實例,如何才能找到類的元數據信息、對象的哈希碼、對象的GC分代年齡等信息。這些信息放在對象的對象頭中。佈局
如今,對虛擬機來講,新的對象已經產生,但對java程序來講,對象纔剛剛開始,由於尚未執行init方法。線程
對象的內存佈局指針
在HotSpot虛擬機中,對象在內存中的存儲的佈局能夠分爲3塊區域:對象頭(Header)、實例數據(Instance Data)、對象填充(Padding)。對象
對象頭包括兩部分的信息:一、用於存儲對象自身的運行時數據:如哈希碼,GC分代年齡,鎖狀態標誌,線程持有的鎖,偏向線程ID,偏向時間戳。2 、存儲類型指針,即對象指向它的類元數據的指針,虛擬機經過這個指針來肯定這個對象是哪一個類的實例。【三、若是對象是一個Java數組,那麼在對象頭中還必須有一塊用於記錄數組長度的數據,由於虛擬機能夠經過普通Java對象的元數據信息來肯定Java對象的大小,可是從數組的元數據中卻沒法肯定數組的大小】內存