
題外話:Java都有對象,那你的對象在哪里呢?那我也來new一個吧。
了解下Java是怎么創(chuàng)建對象,并且在內(nèi)存布局和訪問定位,可以很好的幫助我們認識虛擬機JVM底層的原理。? 這里只是針對HotSpot虛擬機Java對象。
1、對象的創(chuàng)建
創(chuàng)建過程
【虛擬機視角】
1、檢查這個指令的參數(shù)是否能在常量池中定位到一個類的符號引用2、檢查這個符號引用代表的類是否已被加載、 解析和初始化過
3、類未被加載, 那必須先執(zhí)行相應(yīng)的類加載過程
4、為新生對象分配內(nèi)存
5、對象實例字段初始化零值
6、對象必要設(shè)置 ①對象是哪個實例 ②如何才能找到類的元數(shù)據(jù)信息、對象哈希碼(調(diào)用hashCode時計算)、對象的GC分代年齡等信息。
【程序視角】
7、對象創(chuàng)建剛剛開始
① 構(gòu)造函數(shù), 即Class文件中的<init>()方法還沒有執(zhí)行
② new指令之后會接著執(zhí)行<init>()方法, 按照程序員的意愿對對象進行初始化。
并發(fā)問題
方案一:對分配內(nèi)存空間做同步處理——采用CAS重試保證更新操作的原子性
方案二:內(nèi)存分配的動作按照線程劃分在不同的空間之中進行,線程分配緩沖TLAB(Thread Local Allocation Buffer),只有本地緩沖區(qū)用完了, 分配新的緩存區(qū)時才需要同步鎖定。-XX:+/-UseTLAB(開啟關(guān)閉參數(shù))
2、對象內(nèi)存布局
對象頭(Header)用于存儲對象自身的運行時數(shù)據(jù)**:哈希碼(HashCode)、GC分代年齡、鎖狀態(tài)標志、線程持有的鎖、偏向線程ID、偏向時間戳等。

類型指針:
對象指向它的類型元數(shù)據(jù)的指針。
實例數(shù)據(jù)(Instance Data)
對象真正存儲的有效信息**
字段存儲順序
① 虛擬機分配策略參數(shù)(-XX:FieldsAllocationStyle參數(shù))
② 在Java源碼中定義順序
對齊填充(Padding)
①不是必然存在,沒有特別含義
②占位符作用
③對象起始地址必須是8字節(jié)整數(shù)倍--任何對象大小都是8字節(jié)整數(shù)倍
3、對象訪問定位
Java會通過棧上的reference數(shù)據(jù)來操作堆上的具體對象。
訪問方式
句柄
Java堆中將可能會劃分出一塊內(nèi)存來作為句柄池, reference中存儲的就是對象的句柄地址, 而句柄中包含了對象實例數(shù)據(jù)與類型數(shù)據(jù)各自具體的地址信息。

好處
reference中存儲的是穩(wěn)定句柄地址, 在對象被移動(垃圾收集時移動對象是非常普遍的行為) 時只會改變句柄中的實例數(shù)據(jù)指針, 而reference本身不需要被修改。
直接指針
HotSpot虛擬機。Java堆中對象的內(nèi)存布局就必須考慮如何放置訪問類型數(shù)據(jù)的相關(guān)信息,reference中存儲的直接就是對象地址,如果只是訪問對象本身的話,就不需要多一次間接訪問的開銷。

好處
速度更快,它節(jié)省了一次指針定位的時間開銷,由于對象訪問在Java中非常頻繁,因此這類開銷積少成多也是一項極為可觀的執(zhí)行成本。
題外話:Java的對象創(chuàng)建過程多么繁瑣復(fù)雜,那你(直男)在追對象的時候也就不能太著急了。:)
■****總結(jié):
1、對象的創(chuàng)建:從虛擬機的視角和程序的視角。虛擬機的視角就從字節(jié)碼開始,一直進行相關(guān)的初始化過程,程序的視角才是真正執(zhí)行構(gòu)造器時<init>()進行字段的初始化。并且會存在并發(fā)問題,有兩種方案可以解決:一是使用CAS并發(fā)同步,另一種是使用線程分配緩存區(qū)TLAB(類似隔離)。
2、對象的內(nèi)存布局:對象頭、實例數(shù)據(jù)、對齊填充。
- 對象頭:包含了對象運行時的一些數(shù)據(jù),比如:哈希碼(HashCode)、GC分代年齡、鎖狀態(tài)標志、線程持有的鎖、偏向線程ID、偏向時間戳等。
- 實例數(shù)據(jù):對象真正存儲的有效信息,將對象字段等數(shù)據(jù)進行存儲,并且字段存儲的順序是根據(jù)虛擬機分配策略參數(shù)和在源碼中定義的順序來決定的。
- 對齊填充:不是必然存在,只是為了占位符作用,原因是對象起始地址必須是8字節(jié)整數(shù)倍--任何對象大小都是8字節(jié)整數(shù)倍。
3、對象的訪問方式:有句柄和直接指針兩種方式。HotSpot虛擬機使用的是直接指針方式,原因是速度更快,它節(jié)省了一次指針定位的時間開銷。