JVM 參數調優是高併發 Java 系統**穩定性生命線**。配置不當導致頻繁 Full GC、停頓 10s+、甚至 OOM 重啟。作者經歷數月實戰驗證 (日 PV 百萬級、零停頓要求),提煉八大核心經驗並附生產級配置模板 (8G 堆)。
32 位 JVM 最大堆 ~1.5-3G (OS 限制)。64 位 JDK (OpenJDK 8/11/17/21) 支援 TB 級堆。**雖壓縮指標 (Compressed Oops) 使 32G 以內堆無額外開銷**,但 64 位仍是大內存應用唯一選擇。Linux 64 位吞吐量優於 32 位。
-Xms6000m -Xmx6000m
-XX:PermSize=500m -XX:MaxPermSize=500m # JDK 7-
# JDK 8+:
-XX:MetaspaceSize=500m -XX:MaxMetaspaceSize=500m
堆固定避免擴縮容觸發 Full GC、記憶體碎片、GC 日誌噪音。元空間固定防類洩漏撐爆本地記憶體。
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC
-Xloggc:/logs/gc.log
# JDK 9+ 統一日誌:
-Xlog:gc*,gc+heap=debug:file=/logs/gc.log:time,uptime,level,tags:filecount=10,filesize=100m
**GC 日誌是唯一真相來源**。分析工具: GCeasy.io, GCEasy, Artha GC Viewer, JMC, JVisualVM。
現象: YGC 時 Survivor 放不下、老年代也放不下 → 轉 Full GC → 長停頓。
原因一:Survivor 太小/機制不合 → **徹底禁用 Survivor,新生代物件直接進老年代** (適合朝生夕死極高、老年代足夠大的場景):
-XX:SurvivorRatio=65536 # Eden:Survivor = 65536:1 → Survivor 極小
-XX:MaxTenuringThreshold=0 # 年齡閾值 0 → 立即晉升老年代
原因二:老年代空間不足接納晉升物件 → **CMS 並發回收提前介入**,預留空間:
-XX:CMSInitiatingOccupancyFraction=70 # 老年代 70% 佔用啟動 CMS 並發回收
# 核心公式 (作者原創驗證):
# (Xmx - Xmn) * (100 - CMSInitiatingOccupancyFraction) / 100 >= Xmn
# 解讀: 老年代剩餘空間 ≥ 新生代總大小,確保 YGC 最壞情況 (全存活晉升) 也能容納
# 作者配置: Xmx=6000, Xmn=500 → 老年代 5500M。90% 觸發 CMS → 剩餘 550M ≥ 500M (Xmn) → 安全
**永久代/元空間/直接記憶體/線程/文件句柄 均存在不可回收/難回收洩漏風險** (類載入、NIO DirectBuffer、ThreadLocal、JNI、第三方庫)。**每日滾動重啟 (Rolling Restart) 是低成本高可用保障**。K8s `livenessProbe` + `rollingUpdate` / Nginx 上游輪詢剔除 / 滾動發布流水線自動化。
CMS/G1/ZGC 老年代並發回收**不阻塞應用線程** (僅初始標記/重新標記 短 STW)。**犧牲新生代大小 (頻繁 YGC 但極快),換取老年代充裕空間支撐並發回收**,整體停頓可控。作者配置: `Xmn=500M` (總堆 6G),新生代佔比 ~8%。
JAVA_ARGS="
-server
-Xms6000m -Xmx6000m
-Xmn500m
-XX:MetaspaceSize=500m -XX:MaxMetaspaceSize=500m
-XX:SurvivorRatio=65536
-XX:MaxTenuringThreshold=0
-Xnoclassgc
-XX:+DisableExplicitGC
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
-XX:+CMSClassUnloadingEnabled
-XX:-CMSParallelRemarkEnabled
-XX:CMSInitiatingOccupancyFraction=90
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC
-Xloggc:/logs/gc.log
"
CMS 已移除 (JDK 14)。**現代首選 G1 (JDK 9+ 預設) 或 ZGC (JDK 11+ 生產就緒)**。核心邏輯相通:固定堆、詳細日誌、業務感知、預留空間、滾動重啟。G1 關鍵參數: `-XX:MaxGCPauseMillis=200` (目標停頓)、`-XX:G1HeapRegionSize=16m` (Region 大小)。ZGC: `-XX:+UseZGC -Xms6g -Xmx6g` (簡單暴力)。
調優是**持續觀測、假設驗證、業務對齊**的工程實踐,而非參數堆砌。這八條經驗,是從無數個深夜的 GC 日誌與線上故障中煉出的「護身符」。願你用得上,也願你不需要用上。