《深入理解Java虚拟机》笔记-垃圾收集器-CMS
CMS收集器(Concurrent Mark Sweep)
目标:获得最短回收停顿时间
基于标记-清除算法实现
如果应用重视服务的响应速度,希望停顿时间短,给用户好的体验,那CMS收集器就很适合用于这类应用的服务端。
分为四个阶段:
初始标记;
需要Stop The World。仅仅标记GC Roots能直接关联到的对象。
并发标记;
进行GC Roots Tracing 的过程。
重新标记;
修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录。停顿时间一般大于初始标记但远小于并发标记。
并发清除;
耗时最长的就是并发标记和并发清除,不过可以和用户线程一起工作。
Concurrent Mark Sweep收集器运行示意图
CMS收集器的两个优点:
并发收集;低停顿。CMS收集器有三个缺点:
1). 对CPU资源非常敏感。默认启动线程数(CPU+3)/4。当CPU在四个以上时,并发回收时垃圾线程不少于25%的CPU资源。当CPU不足以4个时。CMS对用户程序的影响较大。
2). CMS无法处理浮动垃圾。在并发清理阶段由于用户线程继续执行产生的垃圾称为浮动垃圾。CMS无法在当次的收集中处理掉它们,只好留待下一次GC时再清理掉。需要预留内存,如果预留内存无法满足程序需要,就会出现“Concurrent Mode Failure”。这时虚拟机将启动后背预案:临时启用Serial Old收集器来重新进行老年代的垃圾收集。
3). 基于标记-清除,会产生大量碎片。通过两个参数来缓解。
-XX:+UseCMSCompactAtFullCollection开关。在CMS需要Full GC时开启内存碎片合并整理。
-XX:+CMSFullGCsBeforeCompaction参数。在执行多少次不压缩的Full GC 后,来一次带压缩的。