JVM学习2021-03-03

CMS垃圾回收器最大的问题:虽然能在垃圾回收的同时让系统工作,但是在并发标记和并发清理两个最耗时的阶段,垃圾回收线程和系统工作同时工作,会导致有限的CPU资源被垃圾回收线程占用一部分。会消耗CPU资源

Concurrent Mode Failure 问题

在并发清理期间,系统程序可能先把某些对象分配在新生代,然后触发一次Minor GC ,一些对象进入老年代,短时间又没人引用这些对象,这就是老年代的浮动垃圾

“-XX:CMSInitiatingOccupancyFaction”参数可以用来设置老年代占用多少比例的时候触发CMS垃圾回收。JDK1.6默认的值是92%。也就是说老年代占用92%空间,就自动进行CMS垃圾回收,预留8%的空间给并发回收期间。系统程序把一些新对象放入老年代中。

如果CMS垃圾回收期间,系统程序要放入老年代的对象大于可用内存空间,此时就会发生Concurrent Mode Failure ,就是说并发垃圾回收失败了。

此时会自动采用“Serial Old”垃圾回收器替代CMS,就是直接强行把系统程序“Stop the world”重新进行长时间的GC Roots追踪,标记出所有的垃圾对象,不允许新的对象产生。然后一次性把垃圾对象都回收掉,完事了在恢复系统线程。

所以在生产实践中,这自动触发CMS垃圾回收比例需要合理优化一下,避免Concurrent Mode Failure问题。

 

老年代采用“标记-清理”算法。每次标记出来的垃圾对象,然后一次性回收掉,这样会导致大量的内存碎片产生。碎片太多,会导致后续对象进入老年代找不到连续的内存空间,然后触发Full GC;所以CMS不仅仅用“标记-清理”算法,因为太多的内存碎片实际上会导致更加频繁的Full GC

“-XX:+UseCMSCompactAtFullCollection”参数,默认是打开。

意思是在Full GC 之后要再次进行“Stop the World”,停止工作线程,然后进行碎片整理,就是把存活对象挪到一起。空出来大片的连续内存空间,避免内存碎片。

“-XX:CMSFullGCsBeforeCompaction”参数,默认是0,意思是执行多少次Full GC之后再执行一次内存碎片整理工作。默认是每次Full GC之后都会进行一次内存整理。

 

Q:为啥老年代的Full GC要比新生代的Minor GC慢很多倍?一般在10倍以上?

R:新生代执行速度很快,因为直接从GC Roots出发只要追踪到那些对象是活的就行了,新生代的存活对象很少的,这个速度是极快的,不需要追踪多少对象。

然后直接把存活对象放入Survivor区中,就一次性直接回收Eden和之前使用的Survivor区了。

但是CMS的Full GC,在并发标记阶段,他需要去追踪所有存活对象,老年代存活对象很多,这个过程就会很慢;其次在并发清理阶段,他不是一次性回收一大片内存,而是找到零零散散在各个地方的垃圾对象,速度也很慢;最后完事了,还需要执行一次内存碎片整理,把大量的存活对象给挪到一起,空出来连续内存空间,这个过程还需要Stop the world,那就更慢了。

万一并发清理期间,剩余的内存不足以存放要进入老年代的对象,引发“Concurrent mode Failure”问题,那就更加麻烦了,还得立马用Serial Old 垃圾回收器,“Stop the World ”之后慢慢重新来一遍回收的过程,这更是耗时了。

综上所述,老年代的垃圾回收,就是一个字   “慢”。

 

Q:几个出发老年代GC的时机?

R:第一是老年代的可用内存小于新生代全部对象的大小,如果没有开启空间担保参数,会直接触发Full GC,所以一般空间担保参数都会打开;

第二是老年代可用内存小于历次新生代GC后进入老年代的平均对象大小,此时会提前Full GC;

第三是新生代Minor GC后的存活对象大于Survivor,那么就会进入老年代,此时老年代内存不足。

上述情况都会导致老年代Full GC。

今天加了一个触发时机,就是参数“-XX:CMSInitiatingOccupancyFaction”  参数。设置老年代占用多少比例的时候触发CMS垃圾回收。

刨除掉上述几种情况,如果老年代可用内存大于历次新生代GC后进入老年代的平均对象大小,但是老年代已经使用的内存空间超过了这个参数指定的比例,也会自动触发Full  GC。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值