面试知识库
困难

Full-GC频繁排查#

一句话答案#

Full GC 频繁通常由内存泄漏或参数不当导致,排查路径:GC 日志→jstat 监控→heap dump→MAT 分析支配树。

核心要点

Minor GC(年轻代 GC)触发条件:

  • Eden 区满时触发
  • 特点:频率高,速度快(复制算法 + 存活对象少),STW 时间短(几毫秒到几十毫秒)

Full GC(老年代 + 年轻代 + 方法区)触发条件:

  1. 老年代空间不足(最常见)
  2. System.gc() 被显式调用(建议加 -XX:+DisableExplicitGC 禁止)
  3. Minor GC 的空间担保失败(老年代无法承接晋升的对象)
  4. Metaspace 空间不足
  5. 使用 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:

  1. 减少大对象创建(避免直接进老年代)
  2. 增大年轻代比例(减少对象晋升老年代)
  3. 升级 G1/ZGC(低停顿 GC)
  4. 定期分析 GC 日志,提前发现内存泄漏
面试回答(2分钟版)

Full GC 频繁是线上常见的性能问题,排查思路是四步诊疗法。第一步看 GC 日志,通过 -Xloggc 配置的 GC 日志确认 Full GC 的频率和耗时。第二步用 jstat -gcutil 监控老年代使用率的变化趋势。第三步在合适时机抓 heap dump,可以提前配置 -XX:+HeapDumpOnOutOfMemoryError 自动抓取,也可以用 jmap 手动导出。第四步用 MAT 或 VisualVM 分析堆快照的支配树,找到占用内存最多的对象和引用链,定位问题根因。判断是内存泄漏还是堆太小有一个关键指标:如果每次 GC 后老年代占比持续升高说明是泄漏,如果占比稳定只是堆空间不够就扩大堆。Full GC 的常见触发原因包括老年代空间不足、System.gc 调用、Minor GC 空间担保失败、Metaspace 不足和 CMS 的 Concurrent Mode Failure。减少 Full GC 的方法:少创建大对象、给年轻代足够空间减少对象晋升、升级 G1 或 ZGC 降低停顿。

追问与易错

追问方向:

  • “频繁 Full GC 和内存泄漏是什么关系?”→ 内存泄漏导致老年代对象只增不减,每次 Full GC 回收效果差,很快又满触发下一次;频繁 Full GC 是内存泄漏的典型症状之一
  • “怎么区分是泄漏还是堆太小?”→ GC 后老年代占比持续升高则泄漏,占比稳定只是堆空间不够扩大堆即可
  • “Arthas 怎么在线排查?”→ dashboard 看内存和 GC 概况,heapdump 导出堆快照用 MAT 分析,也可用 vmtool 在线查看对象实例数量定位泄漏对象

易错点:

  • ❌ Full GC 频繁就一定是内存泄漏——也可能是大对象或元空间不足
  • ❌ 不配 HeapDumpOnOOM 导致丢失现场