Full GC没有明确的官方定义,有人认为需要对JVM能够用到的所有共享内存(堆、元空间/永久代、直接内存)进行GC才是Full GC;有人认为只要对整个堆进行了GC(新生代GC+老年代GC)就算是Full GC。在jatat命令的输出中,FGC表示老年代GC,个人倾向于第二种说法。
可能触发Full GC的原因
- 显示调用了System.gc()。
- 老年代空间不足。Minor GC(新生代的GC)时空间分配担保失败,新生代对象晋级老年代,大对象分配空间等情况。如果Full GC后空间仍然不足,则抛出错误:java.lang.OutOfMemoryError: Java heap space。
- 元空间或者永久代满了。如果经过Full GC仍然回收不了,那么JVM会抛出错误信息:java.lang.OutOfMemoryError: Meatespace/PermGen space 。
- 内存泄露也会导致频繁的GC。
- 大量的线程回收,导致GC时间很长。
问题分析定位
- 针对第一种情况,检查代码是否调用了System.gc()。
- 使用
jinfo PID
命令查看JVM的内存配置是否合理,使用jmap
命令检查是否存在内存泄漏、大对象等。具体操作可以参考 OOM问题定位 - 使用
jstat
命令查看GC回收情况和内存使用情况。具体操作可以参考