CMS垃圾回收器


CMS(Concurrent Mark Sweep)收集器,以获取最短回收停顿时间【也就是指Stop The World的停顿时间】为目标,多数应用于互联网站或者B/S系统的服务器端上。其中Concurrent并发是指垃圾收集的线程和用户执行的线程是可以同时执行的。

CMS 垃圾回收器

CMS垃圾回收特点

cms只会回收老年代和永久带(1.8开始为元数据区,需要设置CMSClassUnloadingEnabled),不会收集年轻代;
cms是一种预处理垃圾回收器,它不能等到old内存用尽时回收,需要在内存用尽前,完成回收操作,否则会导致并发回收失败;所以cms垃圾回收器开始执行回收操作,有一个触发阈值,JDK1.6之后默认是老年代或永久带达到92%;

CMS默认启动的回收线程是(处理器核心数量+3 / 4

CMS收集器

CMS是基于“标记-清除”算法实现的,整个过程分为4个步骤:
1、初始标记(CMS initial mark)。
2、并发标记(CMS concurrent mark)。
3、重新标记(CMS remark)。
4、并发清除(CMS concurrent sweep)。

注意:“标记”是指将存活的对象和要回收的对象都给标记出来,而“清除”是指清除掉将要回收的对象。

其中,初始标记、重新标记这两个步骤仍然需要“Stop The World”。

初始标记只是标记一下GC Roots能直接关联到的对象,速度很快。

并发标记阶段就是从GC Roots开始找到它能引用的所有其它对象的过程。

重新标记阶段则是为了修正并发标记期间因用户程序继续动作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短。

CMS收集器的动作步骤如下图所示,在整个过程中耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作,因此,从总体上看,CMS收集器的内存回收过程是与用户线程一起并发执行的:

CMS流程图

  • 优点:并发收集、低停顿【注意:这里的停顿指的是停止用户线程】
  • 缺点:
    1、CMS收集器对CPU资源非常敏感
    2、CMS收集器无法处理浮动垃圾(Floating Garbage,就是指在之前判断该对象不是垃圾,由于用户线程同时也是在运行过程中的,所以会导致判断不准确的, 可能在判断完成之后在清除之前这个对像已经变成了垃圾对象,所以有可能本该此垃圾被回收但是没有被回收,只能等待下一次GC再将该对象回收,所以这种对像就是浮动垃圾),可能出现“Concurrent Mode Failure”失败而导致另一次Full GC的产生。如果在应用中老年代增长不是太快,可能适当调高参数-XX:CMSInitiatingOccupancyFraction的值来提高触发百分比,以便降低内存回收次数从而获取更好的性能。要是CMS运行期间预留的内存无法满足程序需要时,虚拟机将启动后备预案:临时启用Serial Old收集器来重新进行老年代的垃圾收集,这样停顿时间就很长了。所以说参数-XX:CMSInitiatingOccupancyFraction设置得太高很容易导致大量“Concurrent Mode Failure”失败,性能反而降低。
    3、收集结束时会有大量空间碎片产生,空间碎片过多时,将会给大对象分配带来很大麻烦,往往出现老年代还有很大空间剩余,但是无法找到足够大的连续空间来分配当前对象,不得不提前进行一次Full GC。CMS收集器提供了一个-XX:+UseCMSCompactAtFullCollection开关参数(默认就是开启的),用于在CMS收集器顶不住要进行Full GC时开启内存碎片的合并整理过程,内存整理的过程是无法并发的,空间碎片问题没有了,但停顿时间不得不变长。

空间分配担保

在发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么Minor GC可以确保是安全的。当大量对象在Minor GC后仍然存活,就需要老年代进行空间分配担保,把Survivor无法容纳的对象直接进入老年代。如果老年代判断到剩余空间不足(根据以往每一次回收晋升到老年代对象空间的平均值作为经验值),则进行一次Full GC。

CMS运行期间预留的内存无法满足程序分配新对象的需要,就会出现一次‘’并发失败‘,这时候虚拟机将不得不启动后备预案:冻结用户县城的执行,临时启用Serial Old收集器来重新进行老年代的垃圾收集,这样老年代的停顿时间更长了。

引用

CMS垃圾收集器深入详解

CMS垃圾回收器详解

听我的!生产环境的CMS垃圾回收,一定要这样配置参数

从实际案例聊聊Java应用的GC优化


文章作者: WangQingLei
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 WangQingLei !
  目录