一、实时监控与告警(预防阶段)
-
基础监控配置
bashCopy Code
# JVM启动参数 -Xloggc:/logs/gc-%t.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=50M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution -
关键监控指标
- GC频率:Young GC > 10次/分 或 Full GC > 1次/小时(告警阈值)
- 暂停时间:Young GC > 200ms, Full GC > 1s(立即告警)
- 堆内存使用率:Old Gen > 80% 持续10分钟
- 对象晋升速率:通过
jstat -gcutil pid 5s监控
-
监控工具栈
mermaidCopy Code
graph LR A[Prometheus] --> B[JVM Exporter] B --> C[Grafana Dashboard] D[ELK] --> E[GC日志分析] F[APM工具] --> G[应用性能关联]
二、问题诊断六步法
步骤1:确认GC症状
- 高频Full GC:
jstat显示FGC列快速增加 - 长暂停:GC日志中
Times: user=1.25 sys=0.05, real=1.30 secs - 内存不释放:堆使用率持续 >95% 且GC后回收不足
步骤2:获取现场数据
bashCopy Code
# 获取实时GC状态 jstat -gcutil <pid> 1000 10 # 每秒采样,共10次 # 生成堆转储(谨慎使用,避开高峰) jmap -dump:live,format=b,file=heap.hprof <pid> # 抓取线程快照 jstack -l <pid> > jstack.log
步骤3:GC日志分析
关键日志模式:
logCopy Code
[Full GC (Ergonomics) [PSYoungGen: 102400K->0K(204800K)] [ParOldGen: 874521K->880000K(1048576K)] 976921K->880000K(1253376K), [Metaspace: 15321K->15321K(1060864K)], 3.4510286 secs]
- 危险信号:Old Gen回收后占用反而增加(874521K → 880000K)
- Metaspace OOM:
ClassLoader频繁加载/卸载
步骤4:堆内存分析
bashCopy Code
# 使用MAT/Eclipse Memory Analyzer分析 mat heap.hprof
定位方向:
- 支配树:查看占用超1%内存的对象
- OQL查询:
SELECT * FROM java.util.HashMap WHERE size() > 1000 - GC Root链:分析无法回收对象的引用链
步骤5:关联分析
| GC问题现象 | 可能关联原因 |
|---|---|
| Full GC后Old Gen不降 | 内存泄漏/大对象直接进入老年代 |
| Young GC时间陡增 | 新生代过大/存活对象过多 |
| CMS并发模式失败 | 老年代碎片化/晋升速率过快 |
| Metadata GC Threshold | 动态类生成(如CGLib) |
步骤6:根因定位
- 内存泄漏:未关闭资源(DB连接、文件流)、静态集合未清理
- 过早晋升:Survivor空间不足(
-XX:SurvivorRatio不合理) - 外部因素:CPU资源竞争、虚拟内存交换(
vmstat 1查si/so)
三、高频问题应急处理
场景1:突发Full GC风暴
bashCopy Code
# 立即操作 kubectl scale deploy <app> --replicas=2 # 快速扩容分流 jcmd <pid> GC.run # 主动触发Full GC(临时缓解) # 参数临时调整(重启生效) -XX:CMSInitiatingOccupancyFraction=60 # 降低CMS触发阈值 -XX:+UseCMSInitiatingOccupancyOnly
场景2:Metaspace OOM
bashCopy Code
# 紧急恢复 -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=512M # 扩大空间 # 根本解决 arthas watch org.springframework.cglib.proxy.Enhancer destroy # 跟踪类加载
场景3:CMS碎片化
bashCopy Code
# 添加压缩参数 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=1
四、优化验证与防控
-
压测验证
bashCopy Code
# 模拟流量验证优化效果 jmeter -n -t load_test.jmx -l result.jtl -
防控措施
- 代码规约:禁止
static Map缓存无界数据 - 资源约束:容器化部署添加内存限制
yamlCopy Code
# Kubernetes配置 resources: limits: memory: "8Gi" cpu: "4" - GC参数基线:
bashCopy Code
# G1通用配置 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:G1ReservePercent=15 -XX:InitiatingHeapOccupancyPercent=35
- 代码规约:禁止
五、深度排查工具箱
| 工具 | 用途 | 生产安全等级 |
|---|---|---|
| Arthas | 动态诊断(不重启) | ★★★☆☆ |
| async-profiler | 低开销性能分析 | ★★★★☆ |
| Perfino | 实时JVM监控 | ★★★★★ |
| GCViewer | GC日志可视化 | ★★★★★ |
黄金原则:
- 优先保存现场后重启恢复服务
- 变更遵循「测试-预发-生产」流程
- 每次优化只调整一个变量
通过此方案,可系统化解决生产环境90%以上的GC问题,平均恢复时间(MTTR)缩减50%+。

被折叠的 条评论
为什么被折叠?



