iT邦幫忙

2026 iThome 鐵人賽

0
Build on Google AI

把Google AI當夥伴打造個人高效Coding工作流系列 第 22 篇

第二十二天堆積記憶體分代模型、GC Root可達性分析與G1/ZGC演進

  • 分享至 

  • xImage
  •  

一、 弱分代假說(Weak Generational Hypothesis)與記憶體佈局
JVM 將 Heap劃分為不同區域的理論基礎來自於兩條經驗法則:

  • 絕大多數物件都是存活時間極短。
  • 歷經多次垃圾回收仍存活的物件,越傾向於長時間存活。

傳統分代佈局結構:

  • 年輕代(Young Generation):
    • Eden 區:新物件 new 出來時的初始分配地。
    • Survivor 區(S0 / S1,比例預設 8:1:1):採用複製演算法(Copying Algorithm)。每次 Minor GC 後,存活物件在 S0 與 S1 之間來回倒騰,保持其中一塊永遠完全清空,避免記憶體碎片化。
  • 晉升老年代(Tenuring Threshold):
    • 物件每熬過一次 Minor GC,物件頭部(Mark Word)的 Age 計數器就 +1。
    • 達到閥值(預設 15,CMS 預設為 6,受限於 4-bit 欄位上限)時晉升至老年代。
    • 動態年齡判定(Dynamic Age Calculation):若 Survivor 空間中相同年齡所有物件大小的總和大於 Survivor 空間的一半,年齡大於或等於該年齡的物件可直接提早晉升老年代,無須等到 15 歲。
  • 大物件直接進入老年代:超過 -XX:PretenureSizeThreshold 的巨大陣列或字串,避免在 Eden 與 Survivor 間發生大量高成本的記憶體拷貝。

二、 判斷物件生死:GC Roots 可達性分析演算法(Reachability Analysis)
Java 徹底淘汰了老舊的「引用計數法(Reference Counting)」,因為它無法解決物件之間相互循環引用的問題。

  1. 可達性分析邏輯
    從一組明確活躍的起點物件——GC Roots 出發,沿著引用鏈(Reference Chain)向下搜尋。若一個物件到任何一個 GC Root 都沒有可達的路徑,判定該物件為不可達(可回收)。
  2. 哪些物件可以作為「GC Roots」?
  • System Class Loader 載入的核心類別。
  • 虛擬機器棧(JVM Stack)中引用的物件:當前正在執行的執行緒棧幀中的區域變數、傳入參數。
  • 方法區中類別靜態屬性引用的物件:public static Object obj。
  • 方法區中常數引用的物件:字串常數池(String Pool)裡的引用。
  • 本地方法棧(Native Method Stack)中 JNI(C/C++ 代碼)引用的物件。
  • 所有存活的執行緒實體(Thread 物件本身)。
  • 被同步鎖(synchronized)持有的物件。

四、 G1 收集器(Garbage-First):化整為零的 Region 架構
G1 徹底打破了物理上連續的年輕代與老年代劃分,將整個 Heap 均勻切分為數千個大小相等的獨立單元——Region(1MB ~ 32MB,大小為 2 的整數冪)。

  1. 動態角色指派
    每個 Region 在邏輯上隨時可以動態充當 Eden、Survivor、Old,或者是專門存放超過 0.5 個 Region 大小的巨型物件區——Humongous Region。
  2. 「Garbage-First」的核心哲學
    G1 會持續追蹤每個 Region 內部垃圾堆積的回收價值(回收所能釋放的空間與預期花費時間的比值)。
    在後台維護一個優先級清單,每次回收時,根據使用者設定的預期停頓目標(-XX:MaxGCPauseMillis,預設 200ms),優先挑選垃圾最多、回收性價比最高的 Region 進行回收。
  3. 跨區引用解決方案:RSet(Remembered Set)
    問題:若每次回收某個年輕代Region都要掃描整個老年代來確認有沒有引用它,開銷將難以承受。
    機制:每個Region內部都掛載一個RSet,記錄誰引用了我。回收該Region時只需將RSet加入GC Roots掃描,大幅減少掃描範圍。

五、 新一代極致低延遲:ZGC(Z Garbage Collector)架構突破
在JDK 21中,Generational ZGC已正式成為推薦特性,實現了在TB級巨大堆積記憶體 下,STW停頓時間壓制在1毫秒以內 的工業奇蹟。

  1. 核心技術一:染色指真
  • 傳統GC將標記資訊寫在物件頭部的Mark Word中。
  • ZGC直接利用64-bit虛擬位址指標的高位元(Metadata Bits)存儲GC標記狀態:
    • Marked0 / Marked1:標記物件存活狀態。
    • Remapped:記錄該物件指標是否已經完成重新映射。
  1. 核心技術二:讀屏障與併發整理
  • 傳統GC的STW痛點:將物件從舊記憶體位址搬到新位址時,必須暫停所有應用程式執行緒,防止讀寫到錯誤位址。
  • ZGC的併發搬移:
    • GC 執行緒與應用程式執行緒完全並行搬運物件。
    • 當應用程式執行緒嘗試讀取某個正在被搬移的物件時,底層觸發 JIT 編譯器注入的 Load Barrier(讀屏障)。
    • 讀屏障會立即攔截該讀取請求,透過轉發表(Forwarding Table)查詢新位址,直接返回新物件給應用程式,並順手將舊引用修正為新位址(自癒機制,Self-Healing)。

上一篇
第二十一天Record語意、Sealed Classes代數型別與模式匹配完整實戰
下一篇
第二十三天線上故障排查工具箱jstack/jmap/Arthas與OOM/CPU 100%實戰定位
系列文
把Google AI當夥伴打造個人高效Coding工作流 共 23 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言