外观
一句话答案
Full GC 频繁通常由内存泄漏或参数不当导致,排查路径:GC 日志→jstat 监控→heap dump→MAT 分析支配树。
核心要点
Minor GC(年轻代 GC)触发条件:
- Eden 区满时触发
- 特点:频率高,速度快(复制算法 + 存活对象少),STW 时间短(几毫秒到几十毫秒)
Full GC(老年代 + 年轻代 + 方法区)触发条件:
- 老年代空间不足(最常见)
System.gc()被显式调用(建议加-XX:+DisableExplicitGC禁止)- Minor GC 的空间担保失败(老年代无法承接晋升的对象)
- Metaspace 空间不足
- 使用 CMS 时出现 Concurrent Mode Failure(并发清理期间老年代空间不足)
Full GC 期间系统表现(Stop-The-World):
- JVM 暂停(STW):所有用户线程全部停止,包括正在处理请求的线程
- 外部表现: 接口响应超时、请求堆积、监控显示 TP99/TP999 突刺
- 持续时间: 取决于老年代大小和 GC 算法,Serial GC 可能数秒,G1 通常 < 200ms
- 监控特征: JVM GC 日志中出现
[Full GC ...],GC 耗时远高于 Minor GC
如何减少 Full GC:
- 减少大对象创建(避免直接进老年代)
- 增大年轻代比例(减少对象晋升老年代)
- 升级 G1/ZGC(低停顿 GC)
- 定期分析 GC 日志,提前发现内存泄漏
追问与易错
追问方向:
- 频繁 Full GC 和内存泄漏是什么关系?
- 怎么区分是泄漏还是堆太小?(GC 后老年代占比持续升高则泄漏)
- Arthas 怎么在线排查?
易错点:
- ❌ Full GC 频繁就一定是内存泄漏——也可能是大对象或元空间不足
- ❌ 不配 HeapDumpOnOOM 导致丢失现场
💡 记忆锚点
Full GC排查四步诊疗法:看GC日志定频率、jstat监控老年代走势、heapdump抓堆快照、MAT/VisualVM查支配树找泄漏。GC后老年代占比持续升高是泄漏铁证,占比稳定则只是堆太小或大对象太多。