對(duì)象的創(chuàng)建:
1.虛擬機(jī)遇到一個(gè)new指令時(shí)瓮孙,首先將去檢查這個(gè)指令的參數(shù)是否能在常量池中定位到一個(gè)類的符號(hào)引用
2.檢查這個(gè)符號(hào)引用代表的類是否已經(jīng)被加載坊秸,解析和初始化過(guò)麸祷。如果沒(méi)有,那必須先執(zhí)行響應(yīng)的類加載過(guò)程
3.在類加載檢查功通過(guò)后褒搔,為新生對(duì)象分配內(nèi)存阶牍。對(duì)象所需的內(nèi)存大小在類加載完成后便可完全確定喷面。
對(duì)象的內(nèi)存布局:
分為3個(gè)區(qū)域:對(duì)象頭,實(shí)例數(shù)據(jù)走孽,對(duì)齊填充惧辈。
對(duì)象頭:
包括兩部分信息,第一部分:對(duì)象自身的運(yùn)行時(shí)數(shù)據(jù)磕瓷,如哈希碼盒齿,GC分代年齡,鎖狀態(tài)標(biāo)志困食,線程持有的鎖边翁,偏向線程ID,偏向時(shí)間戳等硕盹,這部分?jǐn)?shù)據(jù)的長(zhǎng)度在32位和64位的虛擬機(jī)中分別為32 bit和64 bit符匾,官方稱它為“Mark Word”。
第二部分:類型指針瘩例,即對(duì)象指向它的類元數(shù)據(jù)的指針啊胶,虛擬機(jī)通過(guò)這個(gè)指針來(lái)確定這個(gè)對(duì)象是哪個(gè)類的實(shí)例。如果對(duì)象是一個(gè)java數(shù)組仰剿,那在對(duì)象頭中還必須有一塊用于記錄數(shù)組長(zhǎng)度的數(shù)據(jù)创淡。
實(shí)例數(shù)據(jù):
是對(duì)象真正存儲(chǔ)的有效信息痴晦,也是在程序代碼中所定義的各種類型的字段內(nèi)容南吮。
對(duì)齊填充:
對(duì)齊填充不是必然存在的。HotSpot VM的自動(dòng)內(nèi)存管理系統(tǒng)要求對(duì)象起始地址必須是8字節(jié)的整數(shù)倍誊酌,也就是說(shuō)對(duì)象的大小必須是8字節(jié)的整數(shù)倍部凑。而對(duì)象頭部分正好是8字節(jié)的整數(shù)倍。因此碧浊,當(dāng)對(duì)象實(shí)例數(shù)據(jù)部分沒(méi)有對(duì)齊時(shí)涂邀,就需要通過(guò)對(duì)其補(bǔ)充來(lái)補(bǔ)全了。
對(duì)象的訪問(wèn)定位:
Java程序需要通過(guò)棧上了reference數(shù)據(jù)來(lái)操作堆上的具體對(duì)象箱锐。
目前主流的訪問(wèn)方式有使用句柄和直接指針兩種比勉。
句柄訪問(wèn):
Java堆中會(huì)劃分出一塊內(nèi)存來(lái)作為句柄池,reference中存儲(chǔ)的就是對(duì)象的句柄地址驹止,而句柄中包含了對(duì)實(shí)例數(shù)據(jù)與類型數(shù)據(jù)的各自具體的地址信息浩聋。
直接指針訪問(wèn):
reference中存儲(chǔ)的直接就是對(duì)象地址。