什么时候发生GC

1. Young GC 什么时候触发

Young GC 一般是在新生代的 Eden 区满了之后触发的,之后采用复制算法在 Survivor 的 from 和 to 区之间来回收新生代的垃圾对象。

2. Old GC 和 Full GC什么时候触发

  • 在每次发生 Young GC 之前会进行检查,当老年代可用内存小于新生代全部对象的大小,而这时候没开启空间担保参数(HandlePromotionFailure=false),会直接触发Full GC;当开启空间担保参数(HandlePromotionFailure=true)时,如果【老年代可用的连续内存空间】 < 【新生代历次 Young GC 后升入老年代的对象总和的平均大小】,则说明本次 Young GC 后升入老年代的对象大小可能会超过老年代当前可用内存空间。此时必须先触发一次 Old GC 让老年代腾出更多的空间,而后再执行 Young GC。
  • 那么执行 Young GC 之后有一批对象需要放入老年代,此时老年代就是没有足够的内存空间存放这些对象了,此时必须立即触发一次 Old GC
  • 如果老年代内存使用率超过了 92%,也要直接触发 Old GC,当然这个比例是可以通过参数调整的(Java8中,-XX:CMSInitiatingOccupancyFraction的默认值是92)

其实满足上述一些条件的时候,在 GC 日志中就能看到 Full GC 的字样,同时在 Full GC 中会看到同时对年轻代、老年代、永久代三个区域都进行了垃圾回收。

那么触发 Full GC 的时候,是先执行 Young GC 还是先执行 Old GC?

因为不同的Full GC触发条件其实是不一样的,而且不同的JVM版本的实现机制也不同。所以也没办法给一个准确的定义。

所以我们可以这样说,上述条件满足时触发 Full GC,Full GC一般会带上一次 Young GC 去回收新生代,同时也会有 Old GC 也回收老年代,还会去回收永久代。
 

3. 永久代满了之后会怎么样?

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

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

参考:

http://www.toobug.cn/post/2852.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值