一、先搞懂:GC 日志到底看什么?(核心 4 个指标)
不管什么垃圾回收器,只盯这 4 个值:
- YGC 频率 & 耗时
- 频率太高:Eden 太小 / 瞬时对象太多
- 耗时太长:对象过大、晋升异常
- FGC 次数
- 线上 FGC > 0 就属于风险
- 一天多次 FGC = 必须立刻调优
- GC 总暂停时间(STW)
- 单次 > 500ms 接口会超时
- 累计占比 > 2% 系统不稳定
- 老年代增长速度
- 匀速上涨:正常
- 突刺上涨:内存泄漏 / 大对象 / 池化不当
二、开启 GC 日志(生产标准配置)
JDK8 + CMS
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintTenuringDistribution
-XX:+PrintGCApplicationStoppedTime
-Xloggc:/logs/gc.log
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=5
-XX:GCLogFileSize=100M
JDK11 + G1/ZGC
-Xlog:gc*:/logs/gc.log:time,level,tags
-Xlog:gc+safepoint=trace
三、GC 日志关键字段解读(一眼定位问题)
1)Young GC 典型行
2026-04-16T10:00:00.123+0800:
[GC (Allocation Failure)
[PSYoungGen: 102400K->2048K(153600K)]
122880K->22528K(524288K), 0.012 secs]
Allocation Failure:正常 YGC 原因102400K -> 2048K:年轻代回收前后0.012 secs:STW 耗时(<20ms 合格)
2)Full GC 典型行
[Full GC (System.gc())
[PSYoungGen: 0K->0K(153600K)]
[ParOldGen: 409600K->20480K(409600K)]
409600K->20480K(524288K),
[Metaspace: 12345K->12345K(1056768K)], 0.345 secs]
Full GC:危险信号0.345 secs:STW 345ms,接口必超时- 常见原因:
- 老年代满
- Metaspace 满
- 代码里
System.gc() - 内存泄漏
四、最常用 GC 分析工具(直接用)
- GCeasy(在线,最强)
- GCViewer(本地)
- Arthas dashboard/gc
- jstat -gc 1000 10
最实用命令:
bash
jstat -gc <pid> 1000 10
看:
- YGC/YGCT
- FGC/FGCT
- OC/OU 老年代使用率
五、生产最常见 6 类 GC 问题 + 调优方案
1)YGC 太频繁(1秒多次)
现象
- YGC 间隔 <1s
- 单次耗时低,但总量高
原因
Eden 太小,对象一创建就满
调优
-Xms4g -Xmx4g
-Xmn2g # 加大年轻代
-XX:SurvivorRatio=8
2)YGC 耗时高(>50ms)
原因
- 大对象频繁进入老年代
- Survivor 太小,对象过早晋升
调优
-XX:SurvivorRatio=6
-XX:InitialTenuringThreshold=10
-XX:MaxTenuringThreshold=15
3)老年代持续上涨 → 最终 FGC
90% 是内存泄漏
- 线程池无界
- HashMap/ThreadLocal 缓存不清理
- 数据库连接未释放
- 第三方包 bug
定位
jmap -dump:format=b,file=dump.hprof <pid>
用 MAT 分析 GC Root
调优
修复代码,不是改 JVM 参数。
4)频繁 FullGC(最危险)
可能原因
- 老年代空间不足
- Metaspace 满
- 内存泄漏
- System.gc()
调优
-XX:+DisableExplicitGC # 禁止 System.gc()
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
-Xmx加大
5) Mixed GC 频繁(G1)
原因
- G1 堆太小
- MixedGC 触发阈值不合理
调优
-XX:+UseG1GC
-Xms4g -Xmx4g
-XX:G1HeapRegionSize=16m
-XX:InitiatingHeapOccupancyPercent=50 # 老年代50%开始混合回收
-XX:G1MixedGCCountTarget=8
6)接口超时毛刺 STW
解决方案
高并发微服务直接上 ZGC / Shenandoah
-XX:+UseZGC
-Xms4g -Xmx4g
几乎 无 STW 毛刺。
六、生产级 JVM 启动参数模板
模板1:JDK8 高并发微服务(ParNew + CMS)
-Xms2g
-Xmx2g
-Xmn1g
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=70
-XX:+UseCMSInitiatingOccupancyOnly
-XX:+DisableExplicitGC
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:/logs/gc.log
模板2:JDK17 微服务(G1,通用稳定)
-Xms2g
-Xmx2g
-XX:+UseG1GC
-XX:G1HeapRegionSize=16m
-XX:MaxGCPauseMillis=20
-XX:+DisableExplicitGC
-Xlog:gc*:/logs/gc.log
模板3:超低延迟(支付/网关)ZGC
-Xms4g
-Xmx4g
-XX:+UseZGC
-XX:+DisableExplicitGC
七、调优的真正顺序
- 看业务代码(内存泄漏、大对象、无界集合)→ 占70%问题
- 看对象生命周期
- 调整堆大小、年轻代大小
- 选择 GC 算法
- 精细调阈值