Young GC和Full GC分别在什么情况下会发生

315次阅读
没有评论

共计 1597 个字符,预计需要花费 4 分钟才能阅读完成。

027-Young GC和Full GC分别在什么情况下会发生

大厂面试题:Young GC和Full GC分别在什么情况下会发生?

1. 概述

统一用Young GC指代年轻代gc,用Old GC指代老年代GC,用Full GC指代年轻代、老年代、永久代共同的gc

2. Young GC的触发时机

Young GC其实一般就是在新生代的Eden区域满了之后就会触发,采用复制算法来回收新生代的垃圾

3. Old GC和Full GC的触发时机

 

其实之前的文章里也对Old GC的触发时机说的很清晰了,简而言之就是下面几种情况:

Young GC和Full GC分别在什么情况下会发生

Full GC

(1)发生Young GC之前进行检查,如果老年代可用的连续内存空间 < 新生代历次Young GC后升入老年代的对象总和的平均大小,说明本次Young GC后可能升入老年代的对象大小,可能超过了老年代当前可用内存空间

此时必须先触发一次Old GC给老年代腾出更多的空间,然后再执行Young GC

(2)执行Young GC之后有一批对象需要放入老年代,此时老年代就是没有足够的内存空间存放这些对象了,此时必须立即触发一次Old GC

(3)老年代内存使用率超过了92%,也要直接触发Old GC,当然这个比例是可以通过参数调整的

其实说白了,上述三个条件你概括成一句话,就是老年代空间也不够了,没法放入更多对象了,这个时候务必执行Old GC对老年代进行垃圾回收。

顺便说一句,大家在很多地方看到一个说法,意思是说Old GC执行的时候一般都会带上一次Young GC,可能很多人不理解,其实如果你把咱们这里的几个条件分析清楚了就知道了,一般Old GC很可能就是在Young GC之前触发或者在Young GC之后触发的,所以自然Old GC一般都会跟一次Young GC连带关联在一起了。

另外一个,在很多JVM的实现机制里,其实在上述几种条件达到的时候,他触发的实际上就是Full GC,这个Full GC会包含Young GC、Old GC和永久代的GC,也就是说触发Full GC的时候,可能就会去回收年轻代、老年代和永久代三个区域的垃圾对象。

后面会带大家用各种代码模拟出各种场景,然后观察JVM GC日志,大家会看到,其实满足上述一些条件的时候,在GC日志中看到的就是Full GC的字样,同时在Full GC中大家会看到同时对年轻代、老年代、永久代都进行了垃圾回收。

但是这个东西其实没办法给大家一个准确的定义,说到底触发Full GC的时候,是先执行Young GC?还是先执行Old GC。

因为不同的Full GC触发条件其实是不一样的,而且不同的JVM版本的实现机制也不同。

所以很多时候,我们也只能给大家笼统的概括一句:上述条件满足时触发Full GC,Full GC一般会带上一次Young GC去回收新生代,同时也会有Old GC也回收老年代,还会去回收永久代。

4. 永久代满了之后怎么办?

大家现在既然都知道了,Full GC有上述几个触发条件,同时触发Full GC的时候其实会带上针对新生代的Young GC,也会有针对老年代的Full GC,还会有针对永久代的GC。所以假如存放类信息、常量池的永久代满了之后,就会触发一次Full GC。

这样Full GC执行的时候,就会顺带把永久代中的垃圾给回收了,但是永久代中的垃圾一般是很少的,因为里面存放的都是一些类,还有常量池之类的东西,这些东西通常来说是不需要回收的。如果永久代真的放满了,回收之后发现没腾出来更多的地方,此时只能抛出内存不够的异常了。

5. 本文总结

上篇文章和这篇文章,基本上就把各种GC的概念给屡清楚了,同时结合之前学习到的知识,清楚的限定了各种GC的触发时机。其实整体知识框架跟之前基本上是匹配和吻合的,只不过在各种细化的概念上,做了很多的澄清和限定。

正文完
 0
yangleduo
版权声明:本站原创文章,由 yangleduo 于2023-05-05发表,共计1597字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。