Java對(duì)象

對(duì)象的創(chuàng)建

1.當(dāng)java虛擬機(jī)遇到一條字節(jié)碼new指令時(shí),首先檢查這個(gè)指令的參數(shù)是否能在常量池中定位到一個(gè)類的符號(hào)引用,并且檢查這個(gè)符號(hào)引用代表的類是否已被加載、解析和初始化過(guò)。如果沒(méi)有,執(zhí)行相應(yīng)的類加載過(guò)程。

2.類加載完成后,虛擬機(jī)為新生對(duì)象分配內(nèi)存(內(nèi)存大小在類加載完成后確定),有“指針碰撞”“空閑列表”兩種分配方式。

  • 指針碰撞
    Java堆中內(nèi)存是絕對(duì)規(guī)整的,所有被使用過(guò)的內(nèi)存都被放在一邊,空閑的內(nèi)存被放在另一邊,中間放著一個(gè)指針作為分界點(diǎn)的指示器,那所分配內(nèi)存就僅僅是把那個(gè)指針向空閑空間方向挪動(dòng)一段與對(duì)象大小相等的距離,這種分配方式稱為“指針碰撞”(Bump The Pointer)
  • 空閑列表
    Java堆中的內(nèi)存并不是規(guī)整的,已被使用的內(nèi)存和空閑的內(nèi)存相互交錯(cuò)在一起,虛擬機(jī)就必須維護(hù)一個(gè)列表,記錄上哪些內(nèi)存塊是可用的,在分配的時(shí)候從列表中找到一塊足夠大的空間劃分給對(duì)象實(shí)例,并更新列表上的記錄,這種分配方式稱為“空閑列表”(Free List)。
  1. 內(nèi)存分配完成之后,虛擬機(jī)必須將分配到的內(nèi)存空間(但不包括對(duì)象頭)都初始化為零值。這步操作保證了對(duì)象的實(shí)例字段在Java代碼中可以不賦初始值就直接使用,使程序能訪問(wèn)到這些字段的數(shù)據(jù)類型所對(duì)應(yīng)的零值。

4.Java虛擬機(jī)還要對(duì)對(duì)象進(jìn)行必要的設(shè)置,例如這個(gè)對(duì)象是哪個(gè)類的實(shí)例、如何才能找到類的元數(shù)據(jù)信息、對(duì)象的哈希碼(實(shí)際上對(duì)象的哈希碼會(huì)延后到真正調(diào)用Object::hashCode()方法時(shí)才計(jì)算)、對(duì)象的GC分代年齡等信息。這些信息存放在對(duì)象的對(duì)象頭(Object Header)之中。根據(jù)虛擬機(jī)當(dāng)前運(yùn)行狀態(tài)的不同,如是否啟用偏向鎖等,對(duì)象頭會(huì)有不同的設(shè)置方式。

5.構(gòu)造函數(shù)對(duì)對(duì)象進(jìn)行初始化。

對(duì)象的內(nèi)存布局

對(duì)象在堆內(nèi)存中的存儲(chǔ)布局可以分為三部分:對(duì)象頭,實(shí)例數(shù)據(jù)對(duì)齊填充。

  • 對(duì)象頭
    1."Mark Word",存儲(chǔ)對(duì)象自身的運(yùn)行時(shí)數(shù)據(jù),如哈希碼(HashCode)、GC分代年齡、鎖狀態(tài)標(biāo)志、線程持有的鎖、偏向線程ID、偏向時(shí)間戳等。
    2.類型指針,對(duì)象指向它的類型元數(shù)據(jù)的指針,Java虛擬機(jī)通過(guò)這個(gè)指針來(lái)確定該對(duì)象是哪個(gè)類的實(shí)例。
  • 實(shí)例數(shù)據(jù)
    對(duì)象真正存儲(chǔ)的有效信息。即我們?cè)诔绦虼a里面所定義的各種類型的字段內(nèi)容,無(wú)論是從父類繼承下來(lái)的,還是在子類中定義的字段都必須記錄起來(lái)。
  • 對(duì)齊填充
    占位符的作用。

對(duì)象的訪問(wèn)定位

Java程序會(huì)通過(guò)棧上的(符號(hào)引用)reference數(shù)據(jù)來(lái)操作堆上的具體對(duì)象。

  • 句柄訪問(wèn)

    Java堆中將可能會(huì)劃分出一塊內(nèi)存來(lái)作為句柄池,reference中存儲(chǔ)的就是對(duì)象的句柄地址,而句柄中包含了對(duì)象實(shí)例數(shù)據(jù)與類型數(shù)據(jù)各自具體的地址信息。
  • 直接指針訪問(wèn)

    Java堆中對(duì)象的內(nèi)存布局就必須考慮如何放置訪問(wèn)類型數(shù)據(jù)的相關(guān)信息,reference中存儲(chǔ)的直接就是對(duì)象地址,如果只是訪問(wèn)對(duì)象本身的話,就不需要多一次間接訪問(wèn)的開(kāi)銷。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容