Yige

Yige

Build

JVM系列-HotSpot虛擬機對象探秘

JVM 系列 - HotSpot 虛擬機對象探秘#

內容轉自: HotSpot 虛擬機對象探秘

對象的內存佈局#

在 HotSpot 虛擬機中,對象的內存佈局分為以下 3 塊區域:

  • 對象頭(Header)
  • 實例數據(Instance Data)
  • 對齊填充(Padding)
    image.png

對象頭#

對象頭記錄了對象在運行過程中所需要使用的一些數據:
image

  • 哈希碼
  • GC 分代年齡
  • 鎖狀態標誌
  • 執行緒持有的鎖
  • 偏向執行緒 ID
  • 偏向時間戳

對象頭可能包含類型指針,通過該指針能確定對象屬於哪個類。如果對象是一個數組,那麼對象頭還會包括數組長度。

實例數據#

實例數據部分就是成員變量的值,其中包括父類成員變量和本類成員變量。

對齊填充#

用於確保對象的總長度為 8 字節的整數倍。

HotSpot VM 的自動內存管理系統要求對象的大小必須是 8 字節的整數倍。而對象頭部分正好是 8 字節的倍數(1 倍或 2 倍),因此,當對象實例數據部分沒有對齊時,就需要通過對齊填充來補全。

對齊填充並不是必然存在,也沒有特別的含義,它僅僅起著佔位符的作用。

對象的創建過程#

類加載檢查#

虛擬機在解析.class 文件時,若遇到一條 new 指令,首先它會去檢查常量池中是否有這個類的符號引用,並且檢查這個符號引用所代表的類是否已被加載、解析和初始化過。如果沒有,那麼必須先執行相應的類加載過程。

為新生對象分配內存#

對象所需內存的大小在類加載完成後便可完全確定,接下來從堆中劃分一塊對應大小的內存空間給新的對象。分配堆中內存有兩種方式:

指針碰撞#

如果 Java 堆中內存絕對規整(說明採用的是 “複製算法” 或 “標記整理法”),空閒內存和已使用內存中間放著一個指針作為分界點指示器,那麼分配內存時只需要把指針向空閒內存挪動一段與對象大小一樣的距離,這種分配方式稱為 “指針碰撞”。

空閒列表#

如果 Java 堆中內存並不規整,已使用的內存和空閒內存交錯(說明採用的是標記 - 清除法,有碎片),此時沒法簡單進行指針碰撞, VM 必須維護一個列表,記錄其中哪些內存塊空閒可用。分配之時從空閒列表中找到一塊足夠大的內存空間劃分給對象實例。這種方式稱為 “空閒列表”。

分配策略#

  • 對象優先在 eden 區分配
  • 大對象直接進入老年代,避免為大對象分配內存時由於分配擔保機制帶來的複製而降低效率 (大對象:需要大量連續內存空間的對象,比如字符串、數組)
  • 長期存活的對象將進入老年代

初始化#

分配完內存後,為對象中的成員變量賦上初始值,設置對象頭信息,調用對象的構造函數方法進行初始化。至此,整個對象的創建過程就完成了。

對象年齡判斷#

如果對象在 Eden 出生並經過第一次 Minor GC 後仍然能夠存活,並且能被 Survivor 容納的話,將被移動到 Survivor 空間中,並將對象年齡設為 1. 對象在 Survivor 中每熬過一次 MinorGC, 年齡就增加 1 歲,當它的年齡增加到一定程度(默認為 15 歲),就會被晉升到老年代中。對象晉升到老年代的年齡閾值,可以通過參數 -XX 來設置

動態對象年齡判定:
為了更好的適應不同程序的內存情況,虛擬機不是永遠要求對象年齡必須達到了某個值才能進入老年代,如果 Survivor 空間中相同年齡所有對象大小的總和大於 Survivor 空間的一半,年齡大於或等於該年齡的對象就可以直接進入老年代,無需達到要求的年齡

對象的訪問方式#

所有對象的存儲空間都是在堆中分配的,但是這個對象的引用卻是在堆棧中分配的。也就是說在建立一個對象時兩個地方都分配內存,在堆中分配的內存實際建立這個對象,而在堆棧中分配的內存只是指向這個堆對象的指針(引用)而已。 那麼根據引用存放的地址類型的不同,對象有不同的訪問方式。

句柄訪問方式#

堆中需要有一塊叫做 “句柄池” 的內存空間,句柄中包含了對象實例數據與類型數據各自的具體地址信息。

引用類型的變量存放的是該對象的句柄地址(reference)。訪問對象時,首先需要通過引用類型的變量找到該對象的句柄,然後根據句柄中對象的地址找到對象。

image.png

直接指針訪問方式#

引用類型的變量直接存放對象的地址,從而不需要句柄池,通過引用能夠直接訪問對象。但對象所在的內存空間需要額外的策略存儲對象所屬的類信息的地址。
image.png

需要說明的是,HotSpot 採用第二種方式,即直接指針方式來訪問對象,只需要一次尋址操作,所以在性能上比句柄訪問方式快一倍。但像上面所說,它需要額外的策略來存儲對象在方法區中類信息的地址

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。