简介
CMS全称Concurrent Mark Sweep(并发标记清除),是一款以获取最短回收停顿时间为目标的 老年代收集器,适合基于B/S的服务器上,系统停顿时间短,用户体验较好。
另外,CMS也是一款真正意义上的并发收集器,能够与用户线程同时进行。虽然,并发回收过程中也有几个阶段需要Stop the world,但是由于任务简单,所以停顿时间非常短。
可以通过-XX:+ UseConcMarkSweepGC来标识开启CMS收集器,会使用ParNew对新生代的无用对象进行回收。
回收过程
一、初始标记
- 标记老年代中所有的GC Roots引用的对象
- 标记老年代中被年轻代中活着的对象引用的对象
由于需要对所有的对象进行标记,为了防止标记过程中有对象状态发生改变,所以需要Stop the world,停止用户线程,但是整个标记的过程耗时短。
二、并发标记
- 从初始化标记阶段找到的GC Roots开始进行Tracing,找到所有的存活对象。
并发标记阶段会与用户线程同时进行,因此会有一些对象的引用状态发生改变。
三、重新标记
- 标记在并发标记阶段引用发生变化的对象,如果发现对象的引用发生变化,则JVM会标记堆的这个区域为Dirty Card。
那些能够从Dirty Card到达的对象也被标记(标记为存活),当标记做完后,这个Dirty Card区域就会消失。
该阶段是一个并发阶段,能够与用户线程同时运行,不会中断他们。
四、并发清除
- 移除那些不同的对象,并回收占用的内存空间。
缺点
- CMS收集器对CPU资源(线程数目=(CPU+3)/4)非常敏感。在并发阶段,它虽然不会导致用户线程停顿,但是会因为占用了一部分线程而导致应用程序变慢,总吞吐量会降低。
- CMS收集器无法处理浮动垃圾,可能会出现“Concurrent Mode Failure(并发模式故障)”失败而导致Full GC产生。
- CMS是一款“标记–清除”算法实现的收集器,容易出现大量空间碎片。当空间碎片过多,将会给大对象分配带来很大的麻烦,往往会出现老年代还有很大空间剩余,但是无法找到足够大的连续空间来分配当前对象,不得不提前触发一次Full GC。