Minor GC
介绍
- 年轻代的垃圾回收,该GC会清理伊甸园区和幸存区。
- 因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。
- Minor GC会引发STW:暂停其它用户线程,等垃圾回收结束,用户线程才恢复运行。
触发条件
伊甸园区空间不足会触发,幸存区空间不足不会触发,但是触发Minor GC就会清理伊甸园区和幸存。
触发结果
经过一次Minor GC后
- 伊甸园区没有被回收的对象被放到to区,并且年龄计数器设置为1。
- from区的没有被回收的对象到to区,年龄计数器加一,from和to区交换,此时to为空。
总结:复制之后有交换,谁空谁是to区
Major GC
介绍
- 对老年代的垃圾回收。
- Major GC的速度一般会比Minor GC慢10倍以上,STW的时间更长。
- 如果Major GC后,内存还不足,就报OOM了。
触发条件
老年代空间不足先触发Minor GC,之后空间还不足则触发Major GC( 出现了Major GC,经常会伴随至少一次的Minor GC )
Full GC
介绍
清理整个堆空间,包括年轻代、老年代和元空间(方法区),非常慢。
触发条件
-
调用System.gc(),系统建议执行Full GC,但不是必然执行。
-
老年代空间不足。
-
方法区空间不足。
-
通过Minor GC后进入老年代的平均大小大于老年代的可用内存。
-
from向to复制的时候,对象大小大于to的内存,则把对象转移到老年代,且老年代的的可用内存小于对象大小。
说明:Full GC是开发中尽量避免的,减少Major GC 和 Full GC的发生就是调优。
对象申请堆区空间流程
- 判断伊甸园区是否能放下,如果能放下就放,如果放不下则触发Minor GC。
- Minor GC后伊甸园区能放下就放,如果放不下,说明该对象是超大对象直接放到老年代。
- Minor GC后,在伊甸园区存活的对象要进入幸存区。
- 如果幸存区放不下或者幸存区的对象的年龄计数器大于15,则直接放到老年代。
- 如果老年代也放不下,触发Major GC。
- Major GC后再次判断是否老年代能放下该对象,如果不够说明堆内存空间不够->OOM。
- Minor GC后,在伊甸园区存货的对象要进入幸存区。
总结:垃圾回收频繁发生在新生区,很少发生在养老区,几乎不发生在永久区/元空间