2、当然CMS并不是仅仅 标记-清除,也有参数设置,可以整理。
CMS有一个参数是“-XX:+UseCMSCompactAtFullCollection”,默认就打开了。他意思是在Full GC之后要再次进行“Stop the World”,停止工作线程,然后进行碎片整理,就是把存活对象挪到一起,空出来大片 连续内存空间,避免内存碎片。
还有一个参数是“-XX:CMSFullGCsBeforeCompaction”,这个意思是执行多少次Full GC之后再执行一次内存碎片整理的工作,默认 是0,意思就是每次Full GC之后都会进行一次内存整理。
3、为啥老年代的Full GC要比新生代的Minor GC慢很多倍,一般在10倍以上?
1、在并发标记阶段,他需要去追踪所有存活对象,老年代存活对象很多,这个过程就会很慢;
2、其次并发清理阶段,他不是一次性回收一大片内存,而是找到零零散散在各个地方的垃圾对象,速度也很慢;
3、最后完事儿了,还得执行一次内存碎片整理,把大量的存活对象给挪在一起,空出来连续内存空间,这个过程还得“Stop the World”,那就更慢了。
4、万一并发清理期间,剩余内存空间不足以存放要进入老年代的对象了,引发了“Concurrent Mode Failure”问题,那更是麻烦,还得 立马用“Serial Old”垃圾回收器,“Stop the World”之后慢慢重新来一遍回收的过程,这更是耗时了。
4、所以综上所述,老年代的垃圾回收,就是一个字:慢