對象創(chuàng)建過程
當new一個對象的時候笑窜,首先會檢查這個對象是否已經(jīng)被類加載器加載,沒有加載則按照當前的類加載器去加載(全盤委托機制)有加載或加載完畢后為其分配內(nèi)存空間登疗。
分配內(nèi)存空間
在類加載檢查通過后排截,接下來虛擬機將為新生對象分配內(nèi)存嫌蚤。
劃分內(nèi)存的方法:
- 指針碰撞 :(默認使用指針碰撞)
如果java堆中的內(nèi)存是規(guī)范的,那么一邊是使用過的內(nèi)存一邊是空的內(nèi)存断傲,那么會在中間加一個指針作為分界點的指示器脱吱,分配的內(nèi)存就是把指針向空閑的位置 挪一段與對象大小相同的位置即可 - 空閑列表
如果Java堆中的內(nèi)存并不是規(guī)整的,就必須維護一個列表认罩,記錄上哪些內(nèi)存塊是可用的箱蝠,在分配的時候從列表中找到一塊足夠大的空間劃分給對象實例, 并更新列表上的記錄
初始化
內(nèi)存分配完成后垦垂,虛擬機需要將分配到的內(nèi)存空間都初始化為零值(不包括對象頭)這一步叫初始化
設置對象頭
然后就要設置對象頭虛擬機要對對象進行必要的設置宦搬,例如這個對象是哪個類的實例、如何才能找到類的元數(shù)據(jù)信息劫拗、對象的哈希碼间校、對象的GC分代年齡等信息。這些信息存放在對象的對象頭Object Header之中页慷。
執(zhí)行<"init"> 方法
就是為屬性賦值憔足,賦上程序員賦的那個值,并不是初始化中的零賦值
對象的組成部分
對象是由三部分組成:對象頭(Header)酒繁、 實例數(shù)據(jù)(Instance Data)和對齊填充(Padding)滓彰。
對象頭
對象頭內(nèi)分為三部分
1.Mark Word
Mark Word在32位JVM中的長度是4個字節(jié),在64位JVM中長度是8個字節(jié)
用于存儲對象自身的運行時數(shù)據(jù)州袒, 如哈 希碼(HashCode)揭绑、GC分代年齡、鎖狀態(tài)標志稳析、線程持有的鎖洗做、偏向線程ID、偏向時 間戳等
2.Klass Pointer類型指針(開啟壓縮占4個字節(jié)彰居,未開啟占8個字節(jié))
對象指向它的類元數(shù)據(jù)的指針诚纸,虛擬機通過這個指針來確定這個對象是哪個類的實例。
3.數(shù)組長度
4個字節(jié)陈惰,只有數(shù)組對象有
示例數(shù)據(jù)
對象的實例數(shù)據(jù)就是在代碼中能看到的屬性和他們的值畦徘。
對齊填充
因為JVM要求java的對象占的內(nèi)存大小應該是8個字節(jié)的倍數(shù),所以后面有幾個字節(jié)用于把對象的大小補齊至8個字節(jié)的倍數(shù)