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

Java 垃圾收集器調優實戰:原理、參數與避坑指南

     編輯:Java 相關知識

GC 基礎:為什麼需要垃圾收集?

Java 記憶體管理 = 物件分配 + 物件回收。開發者負責 new,GC 負責識別「不可觸及」物件並回收堆記憶體。核心演算法:可達性分析 (GC Roots → 參考鏈)。

經典收集器與分代假說

收集器代別演算法特點適用場景
Serial新生代/老年代複製/標記-整理單執行緒、Stop-the-world (STW)Client 模式、單核、嵌入式
ParNew新生代複製Serial 多執行緒版、需配合 CMS多核、舊版 CMS 搭配
Parallel Scavenge新生代複製吞吐量優先、自適應調節批次處理、科學計算、Java 8 預設
CMS老年代標記-清除低停頓、併發、碎片化、CPU 敏感響應時間敏感、Java 9 棄用、14 移除
G1全堆區域化標記-整理+複製可預測停頓、Region、記憶體佔用高大堆 (6G+)、Java 9+ 預設
ZGC全堆染色指標+併發整理亞毫秒停頓、支援 TB 級堆、Java 11+超大堆、極低延遲要求
Shenandoah全堆併發整理+轉發指標低停頓、無染色指標依賴、Java 12+大堆、非 x86 平台

關鍵 JVM 參數速查


# 基礎堆設定
-Xms4g -Xmx4g                    # 固定堆大小,避免擴縮抖動
-Xmn1g                           # 新生代大小 (G1/ZGC 通常不設定)

# 收集器選擇
-XX:+UseG1GC                     # G1 (Java 9+ 預設)
-XX:+UseZGC                      # ZGC (Java 11+)
-XX:+UseShenandoahGC             # Shenandoah (Java 12+)

# G1 關鍵調優
-XX:MaxGCPauseMillis=200         # 目標停頓 (預設 200ms)
-XX:G1HeapRegionSize=16m         # Region 大小 1-32MB (2 的冪)
-XX:InitiatingHeapOccupancyPercent=45 # 觸發併發標記閾值 (預設 45%)

# ZGC/Shenandoah
-XX:ZCollectionInterval=5        # 最小收集間隔 (秒)
-XX:ConcGCThreads=4              # 併發 GC 執行緒數

# 通用診斷
-XX:+PrintGCDetails -XX:+PrintGCDateStamps
-Xlog:gc*:file=gc.log:time,uptime,level,tags   # Java 9+ 統一日誌
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dumps

五大調優黃金法則

  1. 先測量再調優:用 jstat、GCLogAnalyzer、Arthas、JProfiler 觀察分配率、晋升率、STW 時間。
  2. 固定堆大小:-Xms = -Xmx,避免擴縮觸發 Full GC。
  3. 新生代別太小:過小導致 Minor GC 頻繁、物件過早晋升老年代;過大延長 STW。經驗值:整體堆 1/3 ~ 1/2 (非 G1/ZGC)。
  4. 選對收集器:
    • 堆 < 4G、吞吐優先 → Parallel GC
    • 堆 4G~16G、平衡 → G1
    • 堆 > 16G、極致低延遲 → ZGC/Shenandoah
  5. 業務代碼層面減壓:
    • 減少短命大物件 (byte[]、StringBuilder 重用)
    • 物件池/緩衝區複用 (Netty ByteBuf、HikariCP)
    • 避免 Finalizer/Cleaner 濫用
    • ThreadLocal 及時 remove()

常見誤區與避坑

誤區真相
System.gc() 能強制回收僅建議,JVM 可忽略;生產嚴禁呼叫
Finalizer 是釋放資源好地方執行不可預測、阻塞 Finalizer 線程會 OOM、Java 9+ 棄用
弱引用/軟引用能解決 OOM只能緩解,根因在於產生速度 > 回收速度
參數抄襲網路「最佳配置」負載特徵不同 (分配率、存活率、堆大小) 必須實測
G1 設定 Region 越小越好過小增加 Remembered Set 開銷,建議 4-32MB

現代觀測工具鏈

  • JDK 內建:jcmd、jstat、jmap、jhat、JFR (Flight Recorder)、jconsole、VisualVM
  • 生產級:Arthas (線上診斷)、async-profiler (低開銷火焰圖)、GCeasy (日誌分析)
  • APM 整合:SkyWalking、Pinpoint、Datadog、Prometheus + JMX Exporter

結語

GC 調優不是玄學,而是「測量 → 假設 → 驗證 → 固化」的工程循環。優先從業務代碼減少分配壓力,再配合適合負載特徵的收集器與參數。記住:最好的 GC 是不需要跑的 GC。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved