垃圾收集器2-CMS收集器
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。
CMS收集器是基于标记-清除算法实现的,整个过程分为4个步骤,包括:
- 初始标记:标记GC Roots能直接关联到的对象,速度很快。
- 并发标记:进行GC Roots Tracing的过程。
- 重新标记:修正并发标记期间因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间比初始标记阶段稍长,但远比并发标记的时间短。
- 并发清除
整个过程中耗时最长的并发标记和并发清除阶段收集器线程都可以与用户线程一起工作,所以总体来说,
CMS收集器的内存回收过程是与用户线程一起并发执行的。收集器运行示意图如下:
CMS收集器的缺点:
-
CMS收集器对CPU资源非常敏感
CMS默认启动的回收线程数=(CPU数量 + 3) / 4
当CPU在4个以上时,并发回收时垃圾手机线程占用不少于25%的资源,随着CPU数量的增加而下降;当CPU不足4个时,收集器线程对用户程序的影响会很大。
-
CMS收集器无法处理浮动垃圾
浮动垃圾指CMS并发清理阶段伴随用户线程运行产生的新的垃圾,这部分垃圾出现在标记过程之后,CMS在当次收集时无法处理掉他们,只能留待下一次GC。
CMS收集器不像其他收集器在老年代几乎填满了在进行收集,需要预留一部分空间提供并发收集时程序运行使用。可以使用-XX:InitiatingOccuoancyFraction参数来修改触发收集的百分比,这个参数设置过高很容易产生Concurrent Mode Failure,导致性能降低。产生这个失败,虚拟机会临时启用Serial Old收集器来对老年代进行垃圾收集,导致停顿时间变长。
-
收集结束会产生大量空间碎片
因为CMS收集器是基于标记-清除算法实现的,所以收集结束会产生大量空间碎片。碎片过多时,可能会出现老年代空间有很大剩余,但无法找到足够大的连续空间来为对象分配,不得不重新触发一次Full GC。
-XX:+UseCMSCompactAtFullCollection参数(默认开启)用于在CMS收集器顶不住要进行FullGC时开启内存碎片的合并整理过程,内存合并的过程是没法并发的,所以停顿时间变长。
-XX:CMSFullGCsBeforeCompaction参数用于设置执行多少次不压缩的Full GC后,跟着来一次带压缩(默认是0,表示每次进入Full GC都进行碎片合并)