学习笔记——CMS收集器

CSM收集器

CSM收集器是一种以获取最短回收停顿时间为目标的收集器。很大一部分应用都会很关注服务的响应速度,以给用户带来良好的交互体验。CMS收集器就非常符合这类应用的需求。
CMS(mark-sweep)从名字上就可以看出它是基于标记——清除算法实现的,整个过程分为以下四个步骤。
一、初始标记(CMS init mark)
二、并发标记(CMS concurrent mark)
三、重新标记(CMS remark)
四、并发清除(CMS concurrent sweep)
初始标记和重新标记阶段需要STW,其他阶段都是并发运行的,初始阶段只是简单的标记一下GCRoot能直接关联的对象,速度很快,并发标记阶段则开始从这些直接关联对象扫描全部的对象,耗时较长,但是可以并发进行。重新标记阶段,则是对并发标记阶段扫描过后,修正因用户程序继续运行而标记产生变动的那一部分对象的标记记录,以增量更新的方式进行标记。所谓增量更新就是,将扫描过的对象产生了引用变动的对象标记为灰色,就也是对象已经被扫描过,但是还有部分引用尚未进行扫描的对象,然后作为GCRoot重新扫描一次,通常比初始标记的STW时间长一些。最后是并发清除阶段,并发的清除已经判断死亡的对象。

缺点

CMS收集器是hotspot虚拟机追求低停顿的第一次成功的尝试,但是有以下三个明显的缺点。
首先,CMS收集器对处理器资源非常的敏感。在并发处理阶段,虽然不会导致线程停顿,但是会占用一部分的线程,导致应用程序变慢,总吞吐量降低。CMS默认启动的回收线程数是(处理器核心数量+3)/4。当核心处理器不足四个时,这时对用户程序的影响就会很大。
其次,CMS无法处理浮动垃圾,有可能出现"Concurrent Mode Failure"失败进而导致另一次完全的STW的FullGC的产生。因为并发标记和并发清除阶段都是并发进行的,这时程序也会产生新的垃圾,CMS无法在当次处理的时候,只能放到下一次GC时才能处理这些垃圾,这部分垃圾就称为浮动垃圾。所以,CMS收集器不能像其他收集器那样等老年代几乎完全填满再进行收集,必须预留一部分空间给并发收集时存储浮动垃圾。可以适当调高参数-XX:CMSInitiatingOccu-pancyFraction的值来提高CMS的触发百分比,所谓触发的百分比就是说,当老年代空间占满百分之多少的时候就进行FullGC。如果CMS运行期间预留的内存无法满足程序分配新的对象的需求,就会出现一次"并发失败",(Concurrent Mode Failure)。这是采用后备预案,临时启用Serial Old收集器来重新收集老年代的垃圾,但这样停顿的时间就太长了。所以参数-XX:CMSInitiatingOccu-pancyFraction得根据实际情况设置。
最后一个缺点,因为CMS收集器是根据标记——清除算法,意味着收集结束的时候有大量空间碎片产生,将会给大对象的收集带来许多麻烦,当老年代还有很多剩余空间,但却无法找到足够大的空间来分配当前大对象的时候,就会提前触发一次FullGC,为了解决这个问题,CMS提供了一个参数, -XX:+UserCMSCompactFullCollection开关参数(默认是开启的,jdk9之后废弃),用于CMS不得不进行FullGC的时候开启内存碎片的整理过程,由于整理要移动获得对象,在ZGC和Shenandoah出现前是不能并发的,所以很耗时,虚拟机设计者提供了另一个参数,-XX:CMSFullGCBeforeCompaction(jdk9之后废弃),这个参数的作用是在CMS经过若干次不进行碎片整理的FullGC后,次数由参数设定(默认是0,每次FullGC都进行),再下一次FullGC之前先进行碎片管理。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值