GC的全称是garbage collection,中文名称垃圾回收,那么MinorGC、MajorGC、FullGC对应的就是新生代垃圾回收、老年代垃圾回收、全部回收。

MajorGC一般认为就是FullGC,即整体回收heap堆,但是由于HotSpot VM发展,对这两个概念已经混乱了,所以,当有人问的时候就问清楚是FullGC还是老年代GC,这里将MajorGC认为是老年代GC。

MinorGC

MinorGC指的是新生代的垃圾回收。

在前面的JVM1.8内存模型中,我们知道,堆中分为新生代和老年代,其中新生代又包含Eden(伊甸园)Survivor(幸存者)两个区。

当Eden(伊甸园)中的内存满了变会触发MinorGC的执行。在执行MinorGC后,

如果对象还存活,则将它放到Survivor(幸存者区),之后每次执行Minor GC,
如果对象还存活,就将该对象的年龄加1,当对象的年龄超过15(默认值),则进入老年代。

MajorGC

这里将MajorGC认为是老年代GC。

一般出现一次MajorGC会至少伴随一次MinorGC,也有例外,在Parallel Scavenge收集器的收集策略里就有直接进行Major GC的策略选择过程。

老年代的回收条件是老年代的空间不足,会先尝试触发Minor GC,如果之后空间还不足,则触发Major GC。

  • Major GC的速度一般会比Minor GC慢10倍以上,STW的时间更长
  • 如果Major GC后,内存还不足,就报OOM了
  • Major GC的速度一般会比Minor GC慢10倍以上

FullGC

FullGC是针对整个heap堆而言的,包括新生代和老年代,是对JVM内存堆的整体回收。

触发FullGC可能的原因。

System.gc()

在代码中调用System.gc()方法只是建议JVM进行FullGC,但是虚拟机未必执行,可以使用-XX:+ DisableExplicitGC来禁止RMI调用System.gc。

老年代空间不足

当创建过大的对象或者数组,Eden(伊甸园)放不下,会直接放到老年代,而老年代的空间也不足了,便会执行fullgc,全部回收。所以,不要创建过大的对象或数组。

标记复制算法

使用标记复制算法的 Minor GC 需要老年代的内存空间作担保,如果担保失败会执行一次 Full GC。