CMS收集器
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器;这款收集器是HotSpot虚拟机中第一款真正意义上支持并发的垃圾收集器,首次实现了让垃圾收集线程与用户线程(基本上)同时工作。
适用于:互联网网站或者基于浏览器的B/S系统的服务端
具体步骤
基于标记-清除算法实现的,具体步骤分为4步:
1.初始标记:Stop The World -> 标记一下GC Roots能直接关联到的对象,速度很快
2.并发标记:从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行;基于增量更新做的并发标记
3.重新标记:Stop The World -> 为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录;时间:比初次标记稍长,远远小于并发标记时间
4.并发清除:清理删除掉标记阶段判断的已经死亡的对象,由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的。
Stop The World:必须全程暂停用户应用程序才能进行对象移动操作。
由于在整个过程中耗时最长的并发标记和并发清除阶段中,垃圾收集器线程都可以与用户线程一起工作,所以从总体上来说,CMS收集器的内存回收过程是与用户线程一起并发执行的。
优点
并发收集、低停顿
缺点
1.CMS收集器对处理器资源非常敏感:在并发阶段,CMS会和用户进程一起执行,但却会因为占用部分线程,导致应用程序变慢,降低吞吐量;当处理器核心数量不足4个时,CMS对用户程序的影响就可能变得很大(处理器核心数在4个以上,只占用不到25%的处理器运算资源)
2.由于CMS收集器无法处理“浮动垃圾”,有可能出现“Con-current Mode Failure”失败进而导致另一次完全“Stop The World”的Full GC的产生
浮动垃圾
在并发标记和清除阶段,由于是和用户进程并发执行的,垃圾收集的同时,用户还会随之产生垃圾对象,由于这部分垃圾是在标记之后产生,CMS无法当次处理完成,只好等到下次垃圾收集时处理,这部分垃圾就称为浮动垃圾。
由于CMS是个支持并发的收集器,部分内存需要分配给并发收集程序使用,就不会等到老年代快满了再去收集;在JDK5默认设置下,CMS收集器当老年代使用了68%的空间后就会被激活,这个值可以调高一些,但会发生并发失败”(Concurrent Mode Failure:CMS运行期间预留的内存无法满足程序分配新对象的需要)风险。
发生并发失败
就会冻结用户线程的执行,临时启用Serial Old收集器来重新进行老年代的垃圾收集,但这样停顿时间就很长了,性能反而降低了。
3.产生大量的空间碎片:CMS是一款基于“标记-清除”算法实现的收集器
空间碎片过多时,将会给大对象分配带来很大麻烦,往往会出现老年代还有很多剩余空间,但就是无法找到足够大的连续空间来分配当前对象,而不得不提前触发一次Full GC的情况。
-> 使用时注意:使用CMS收集器时,不要分配过大的内存,如果内存过大,会很长时间才触发一次stop the world,但一次时间也会因数据量过大而造成用户线程停止时间过长的问题。如果一个服务器内存很大,需要把它虚出很多台小的服务器,每台服务器上独立安装java做成集群,这样使用CMS收集器就会避免上述情况发生。