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

JVM 垃圾收集器全景圖:Serial、Parallel、CMS、G1 核心機制與選型指南

     編輯:關於C++

收集器分代佈局

JVM 堆劃分為新生代(Young)與老年代(Old)。不同收集器作用於不同代,且存在配對關係:

新生代收集器老年代收集器可搭配
SerialSerial Old✓
ParNewCMS / Serial Old✓
Parallel ScavengeParallel Old✓
G1G1 (整堆)獨立

七大經典收集器深度解析

1. Serial 收集器

  • 單線程、Stop-The-World (STW)
  • 新生代:複製算法;老年代:標記-整理
  • Client 模式默認,單 CPU 環境最高效(無線程切換開銷)

2. ParNew 收集器

  • Serial 的多線程版,同樣用複製算法
  • 唯一能與 CMS 搭配的新生代收集器
  • 多 CPU 時優於 Serial,但單 CPU 因線程管理反而較慢

3. Parallel Scavenge 收集器

  • 新生代、複製算法、多線程
  • 目標:可控吞吐量 = 用戶代碼時間 / (用戶代碼時間 + GC 時間)
  • 自適應調節策略(-XX:+UseAdaptiveSizePolicy)自動調整新生代大小、晉升閾值
  • 適合後台計算、批處理類無交互應用
  • 不能與 CMS 搭配

4. Serial Old 收集器

  • Serial 老年代版,單線程、標記-整理、STW
  • Client 模式默認老年代收集器
  • 也作為 CMS 失敗時的備選(Concurrent Mode Failure)

5. Parallel Old 收集器

  • Parallel Scavenge 老年代版,多線程、標記-整理
  • JDK 1.6+ 提供,配合 Parallel Scavenge 組成「吞吐量優先」組合

6. CMS 收集器

  • 目標:最短停頓時間,老年代、標記-清除
  • 四階段:
    ① 初始標記 (STW) - 僅標記 GC Roots 直達對象,極快
    ② 並發標記 - GC Roots Tracing,耗時長但與用戶線程並發
    ③ 重新標記 (STW) - 修正並發階段變動,較短
    ④ 並發清除 - 與用戶線程並發
  • 優點:低停頓、並發收集
  • 缺點:
    ① CPU 敏感(佔用核心導致應用變慢)
    ② 無法處理浮動垃圾(並發產生的新垃圾,下次 GC 清理)
    ③ 內存碎片(標記-清除不整理),大對象分配困難觸發 Full GC

7. G1 (Garbage-First) 收集器

  • JDK 1.7+,面向服務端、大堆(>4GB)、多核
  • 不再物理劃分代,堆劃分為多個大小固定(1-32MB)Region
  • 每個 Region 動態扮演 Eden/Survivor/Old 角色
  • Remembered Set (RSet) 記錄跨 Region 引用,實現 Region 級並行回收
  • 四階段:初始標記(STW) → 並發標記 → 最終標記(STW,多線程) → 篩選回收(STW,按回收價值優先級)
  • 核心優勢:
    ① 可預測停頓:指定目標停頓時間,優先回收垃圾最多 Region
    ② 無碎片:基於標記-整理,Region 間復制壓縮
    ③ 大堆友好:增量式回收,避免全堆掃描

關鍵概念辨析

概念Serial/ParallelCMS/G1
並行多 GC 線程同時工作,用戶線程暫停GC 線程與用戶線程同時運行
目標高吞吐量低停頓
算法複製/標記-整理標記-清除/標記-整理

選型建議

  • 單核/小堆/Client:-XX:+UseSerialGC
  • 多核/批處理/高吞吐:-XX:+UseParallelGC (+ UseParallelOldGC)
  • 多核/交互應用/低延遲:-XX:+UseParNewGC -XX:+UseConcMarkSweepGC
  • 大堆(>6GB)/多核/可預測停頓:-XX:+UseG1GC
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved