Java虛擬機(二) - 對象 創建流程、內存分配

一、對象的創建流程

從虛擬機的視角,對象創建完成了,對於Java來說,對象創建纔剛剛開始,方法還沒有執行,所有字段都還是零
虛擬機遇到一條new指令
檢查指令參數是否能在常量池中定位到一個類的符號引用,並檢查這個符號引用代表的類是否已被加載解析和初始化過
爲新生對象分配內存
執行類加載過程
將分配到的內存空間都初始化爲零值,不包括對象頭
虛擬機對對象進行必要的設置,例如對象是哪個類的實例,如何找到類的元數據信息,對象的哈希碼等
執行init方法,把對象按照程序員的意願進行初始化

二、對象的內存佈局

在HotSpot(sun jdk和openJDK中所帶的虛擬機,是目前使用最廣的虛擬機)虛擬機中,對象在內存中存儲的佈局可以分爲3塊區域:對象頭(Header)、實例數據(Instance Data)和對齊信息(Padding)。

1、對象頭

對象頭包含兩部分信息

第一部分(Mark Word)
用於存儲對象自身的運行時數據,如哈希碼、GC分代年齡、鎖狀態標誌、線程持有的鎖、偏向線程ID、偏向時間戳等。
Mark Word數據的長度在32位和64位的虛擬機(未開啓壓縮指針)中分別爲32bit和64bit

  • GC分代年齡
    HotSpot使用分代垃圾回收機制,被分爲三個代:年輕代(Young Generation)、年老代(Old Generation)和持久代(Permanent Generation)。
    (1)年輕代:所有新生成的對象首先都是放在年輕代的。年輕代的目標就是儘可能快速的收集掉那些生命週期短的對象。
    (2)年老代:在年輕代中經歷了N次垃圾回收後仍然存活的對象,就會被放到年老代中。因此,可以認爲年老代中存放的
    都是一些生命週期較長的對象。
    (3)持久代:用於存放靜態文件,如今Java類、方法等。

注意:Java8去除了持久代

  • 鎖狀態標誌
    Mark Word的最後2bit是鎖狀態標誌位,用來標記當前對象的狀態。對象的所處的狀態決定了Mark Word存儲的內容,如下表所示:
狀態 標誌位 存儲內容
未鎖定 01 對象哈希碼、對象分代年齡
輕量級鎖定 00 指向鎖記錄的指針
膨脹(重量級鎖定) 10 執行重量級鎖定的指針
GC標記 11 空(不需要記錄信息)
可偏向 01 偏向線程ID、偏向時間戳、對象分代年齡

第二部分(類型指針)
對象指向它的類元數據的指針,虛擬機通過這個指針來確定這個對象是哪個類的實例。

2、實例數據
實例數據是對象真正存儲的有效信息,也是在程序代碼中所定義的各種類型的字段內容。

3、對齊填充
不必然存在,也沒有特別的含義,僅僅起了佔位符的作用。HotSpot VM 規定對象的大小必須是8字節的整數倍,當對象實例數據沒有對齊時,需要對齊填充補全

三、對象的內存分配

Java自動內存管理最終可歸結爲自動化的解決了兩個問題:給對象分配內存及回收分配給對象的內存。

  1. 對象優先在Eden(新生代Eden區)分配
    如果Eden沒有足夠的空間分配,虛擬機將發起一次Minor GC
  2. 大對象直接進入老年代
    大對象是指需要大量連續內存空間的Java對象,最典型的大對象就是很長的字符串以及數組。
  3. 長期存活的對象將進入老年代
    每個對象有個年齡計數器。如果對象在Eden出生並經過第一次Minor GC後仍然存活,並且能被Survivor容納的話,將被移動到Survivor空間中,並且對象年齡設爲1.對象在Survivor每熬過一次Minor GC,對象年齡加1。當對象到達15(默認15,通過-XX:MaxTenuringThreshold設置)的時候,將被晉升到老年代。
  4. 並不是所有對象年齡必須到達MaxTenuringThreshold才能晉升老年代
    如果Survivor空間中,相同年齡所有對象大小的總和大於Survivor空間的一半,年齡大於或等於該年齡的對象可以直接進入老年代。

四、其他

  • Minor GC (新生代GC)
    發生在新生代的垃圾收集動作,Minor GC非常頻繁,回收速度快。
  • Major GC / Full GC (老年代GC)
    發生在老年代的GC,出現Major GC,經常會伴隨至少一次的Minor GC(不絕對)。Major GC的速度一般比Minor GC 慢10倍以上。
  • Eden 、 Survivor
    新生代分爲一個Eden區,兩個Survivor區。Eden和Survivor的空間大小比例是8:1

[1] 周志明 · 深入理解Java虛擬機 :機械工業出版社
[2] GC分代相關概念摘自 https://www.cnblogs.com/weiguo21/p/5195460.html
[3] 鎖狀態標誌相關摘自 https://blog.csdn.net/kirito_j/article/details/79201213

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章