Java频繁GC的完整排查流程与解决方法
频繁GC 是Java最常见的线上故障之一,直接表现:CPU 高、响应慢、卡顿、甚至OOM。
我给你一套最实用、最快定位的排查步骤,从查看GC情况 → 定位原因 → 解决问题,全程不猜、不重启。
一、先确认:是不是真的频繁GC?
1. 看GC实时状态(最关键)
jstat -gc <PID> 1000 10
每1秒输出一次GC,共10次。
重点看这4列
- YGC:YoungGC 次数(每秒涨好几次 = 频繁YoungGC)
- YGCT:YoungGC 总耗时
- FGC:FullGC 次数(只要一直在涨 = 严重问题)
- FGCT:FullGC 总耗时
判定标准(线上通用)
- FGC 每分钟 ≥1 次 → 严重频繁GC,必须立刻处理
- YGC 每秒 ≥2 次 → 频繁YoungGC
- GC耗时占比 >10% → 影响业务
二、快速判断:频繁GC 分 3 种类型
1.频繁 FullGC(最危险)
症状:CPU 高、应用卡顿、FGC 疯狂上涨
原因:内存泄漏、堆内存不足、大对象、元空间溢出
2.频繁 YoungGC
症状:YGC 很高,但FGC不涨
原因:新生代太小、创建对象太快
3.YoungGC 高 + 慢慢触发 FullGC
原因:内存泄漏(最常见)
三、3步定位频繁GC根因(实战流程)
第一步:看堆内存使用情况
jmap -heap <PID>
重点看:
- 堆总配置
- 老年代使用率
- 元空间使用率
如果老年代快满了还在涨 → 内存泄漏。
第二步:导出堆快照(定位谁在占用内存)
jmap -dump:format=b,file=heap.hprof <PID>
注意:
- 生产导出时会STW,建议低峰期执行
- 或者加参数:
-dump:live,format=b...只抓存活对象(更快)
第三步:分析堆快照(找泄漏代码)
用以下工具打开 heap.hprof:
- Eclipse MAT(最强)
- JProfiler
- IDEA 自带 Profiler
你重点找这3类问题
- 某个业务对象实例数暴增(内存泄漏)
- 超大集合(List/Map 只加不删)
- 静态变量缓存了大量对象(最常见泄漏点)
四、90% 的频繁GC 就这 5 种原因
1.内存泄漏(最常见)
特征:FGC 越来越频繁,老年代回收不掉
典型代码:
- static Map 不断put数据,不清理
- 线程池使用不当,ThreadLocal 没remove
- 流、连接未关闭
2.堆内存太小
特征:GC 后内存依然占满
解决:加大 -Xmx
3.创建大对象/瞬时对象过多
比如:超大List、批量查询、JSON序列化
特征:YGC 非常频繁
4.元空间溢出
特征:FGC,OGF: Metaspace
原因:反射、动态代理、大量类加载
5.直接内存泄漏
NIO/Netty 未释放直接内存,导致频繁FullGC
五、1分钟快速排查命令(直接复制)
# 1. 找Java进程 ps -ef | grep java # 2. 实时GC监控 jstat -gc <PID> 1000 # 3. 看堆内存 jmap -heap <PID> # 4. 导出堆dump jmap -dump:live,format=b,file=heap.hprof <PID> # 5. 看线程栈(排查CPU+GC关联) jstack <PID>
六、解决方案(直接对照用)
1. 内存泄漏
修复代码:
- 用完的集合清空
- ThreadLocal 调用 remove()
- 关闭流/连接
- 缓存加过期、加淘汰策略
2. 新生代太小
-Xmn2g 或调整 NewRatio
3. 堆太小
-Xms4g -Xmx4g
4. 元空间太小
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m
5. 对象创建太快
优化批量查询、减少大对象、异步、缓存
七、最实用的GC排查口诀
FGC频繁查泄漏, YGC频繁看对象, 堆满就是内存漏, 泄漏都在集合里。
总结
- jstat -gc 确认频繁GC
- jmap -dump 导出堆
- MAT 分析谁占内存
- 90% 是static集合、ThreadLocal、缓存无回收导致泄漏
以上就是Java频繁GC的完整排查流程与解决方法的详细内容,更多关于Java频繁GC排查与解决的资料请关注脚本之家其它相关文章!
相关文章
解决在Gradle/IDEA中无法正常使用readLine的问题原因
这篇文章主要介绍了在Gradle/IDEA中无法正常使用readLine的解决方法,原因是由于Gradle的标准输入默认并不与系统标准输入绑定,需手动设置,需要的朋友可以参考下2021-12-12
springboot基于keytool实现https的双向认证示例教程
这篇文章主要介绍了springboot基于keytool实现https的双向认证,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2023-06-06


最新评论