[ JVM ] 垃圾什么时候回收?
垃圾回收是面试中很重要的话题,整个垃圾回收的知识点也非常多,一整篇看下来的话可能会对一些细节不是很深刻,所以我个人喜欢把大问题拆分成小问题来集中处理。
所以这一章我们集中来讨论Java中的垃圾什么时候回收,更为具体的话就是”垃圾回收的触发机制“,
由于不同的垃圾回收算法的触发机制不一,所以我们分为两章来讨论。
经典垃圾回收触发机制
在G1出现以前,Gc分为两种,即YoungGc和FullGC(或者称为MinorGc和MajorGC)
YoungGC
顾名思义,YoungGC是发生在年轻代的GC,在Eden区没有足够的空间创建新对象时,就会触发YGC,即复制算法进行回收。
延申知识:对象怎么进入老年代?
有如下途径:
- 最为常见的,经过了多次YGC后还存货的对象进入老年代
- 动态年龄判断,相同年龄的对象,若达到了Survivor区的一半以上,则大于该年龄的对象直接进入老年代
- YGC时空间不足时,超出的对象直接进入老年代
- 大对象直接进入老年代
FullGC
FullGC是老年代的GC,怎么才能触发老年代的GC呢?
我们直观的想一想:
- 当老年代的使用率达到一定的阈值后,肯定会触发FGC
- 刚刚我们说到YGC空间不足时会将对象存放进老年代,在这之前,若老年代的空间也不够的话,也会触发FGC
- 我们显示的调用System.gc() Runtime.gc()时,也会触发
- jdk8以后,方法区中的数据会存放在元空间(metaspace)中,该空间也存在与堆区,当元空间空间不足时,也会触发FGC
另外,在CMS回收器中,会进行垃圾的并发清理
G1垃圾回收触发机制
G1的垃圾回收相对来说有点不同,分为YGC和MixGC。
YGC和上述差不多,都是对Eden区和Survivor区进行复制算法的回收。
MixGC在老年代的使用率达到一定的阈值后会触发,默认为65%。
另外,MixGC不会回收所有的region,而是维护了一个由使用率进行排序的队列,优先回收使用率高的region,从而尽量的达到用户设置的回收时间。