首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java GC 垃圾收集器核心機制與交互原理淺析

     編輯:Java 相關知識

Java 垃圾收集器 (GC) 是 JVM 自動內存管理的核心。本文從 GC 根節點枚舉、安全點/安全區域、記憶屏障、收集器分類、交互協作五個維度,系統梳理 GC 核心機制與收集器間協作原理。

1. GC 根節點枚舉:追踪的起點

  • 定義:GC Roots 是對象存活分析的起始節點集合。
  • 包含:
    • 虛擬機棧局部變量表引用的對象
    • 方法區類靜態屬性/常量引用的對象
    • 本地方法棧 JNI 引用的對象
    • 同步鎖持有的對象
    • JVM 內部對象(如 Class 對象、異常實例等)
  • 枚舉優化:使用 OopMap 精確知道哪個位置存引用,避免全棧掃描;在安全點掃描 Roots。

2. 安全點與安全區域:讓線程「停下來」

概念說明
安全點代碼執行到特定位置(方法調用、循環跳轉、異常跳轉)時,線程可安全暫停,GC 掃描棧帧。JVM 通過輪詢或中斷信號讓線程主動進入安全點。
安全區域代碼片段中引用關係不變的區域(如睡眠、阻塞、JNI 關鍵區)。線程進入時標記,GC 期間無需掃描其棧,退出時檢查是否需補掃。

關鍵:Stop-the-World (STW) 時刻所有線程必須在安全點/區域,才能進行 Roots 枚舉與堆遍歷。

3. 記憶屏障與寫屏障:維護引用關係

  • 寫屏障:引用賦值前/後插入的攔截邏輯。用途:
    • 維護記憶集,支援分代收集(老年代→新生代引用記錄)
    • 實現併發標記的增量更新或 SATB (Snapshot-At-The-Beginning)
  • 讀屏障:對象讀取時攔截,用於併發移動收集器(如 ZGC、Shenandoah)保證訪問到正確對象副本。
  • 實現:JVM 層面插入汇編指令,Java 代碼無感知。

4. 主流收集器分類與特點

收集器代別算法併發度適用場景
Serial新/老複製/標整串行 STWClient 模式、小堆、單核
ParNew新複製多線程 STW配合 CMS、多核新生代
Parallel Scavenge新複製多線程 STW吞吐量優先、科學計算
CMS老標清併發標記/清除低延遲、舊版主流(JDK 9 棄用)
G1全堆標整+複製併發標記、混合收集大堆 (>4G)、可預測停頓、JDK 9+ 默認
ZGC全堆染色指標+讀屏障高度併發超大堆 (TB 級)、亞毫秒停頓、JDK 11+
Shenandoah全堆併發移動+讀屏障高度併發大堆、低延遲、OpenJDK 項目

5. 收集器交互與組合規則

  • 新生代 + 老年代配對:Serial+SerialOld、ParNew+CMS、Parallel+ParallelOld、G1(自管理)、ZGC/Shenandoah(自管理)。
  • 跨代引用處理:老年代收集器需掃描新生代對象(或通過記憶集 Card Table 記錄老→新引用)。CMS 併發標記階段需處理漏標(重新標記 STW)。
  • 晉升失敗:新生代對象晋升老年代時空間不足,觸發 Full GC(CMS 常見問題)。
  • G1/ZGC 無分代邊界:以 Region 為單位,混合收集若干 Region,邏輯上仍有新/老但物理連續。

6. 選型建議 (JDK 17+)

  1. 堆 < 4G、追求吞吐:-XX:+UseParallelGC
  2. 堆 4G-16G、平衡延遲/吞吐:-XX:+UseG1GC (默認)
  3. 堆 > 16G、極致低延遲:-XX:+UseZGC (生產就緒)
  4. 需兼容 JDK 8:G1 或 CMS (慎用),或升級 JDK。

核心參數速查

-Xms -Xmx          堆初始/最大
-XX:NewRatio       老年代/新生代比例
-XX:SurvivorRatio  Eden/Survivor 比例
-XX:MaxGCPauseMillis G1/ZGC 目標停頓
-XX:+PrintGCDetails -Xlog:gc*  GC 日誌 (JDK 9+ 統一格式)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved