1 简介
- CMS: (concurrent-Mark-Sweep) 收集器,是HotSpot虚拟机中第一款并发收集器,实现了让垃圾收集线程与用户线程同时工作。
- CMS收集器关注是:尽可能缩短垃圾收集时用户线程的停顿时间。停顿时间越短(低延迟)就越适合与用户交互的程序,良好的响应速度能提升用户体验。
- CMS的垃圾收集算法采用标记-清除算法,并且也会"stop-the-world”。(任何一个垃圾收集器会"stop-the-world”)
- CMS垃圾收集器无法和ParallelGC搭配工作,只能和ParGC,SerialGC其中一个。
2 CMS工作原理
- CMS主要分为4各阶段:即初始化标记阶段、并发标记、重新标记、并发清理阶段。
- 初始标记阶段:程序中所有的工作线程都将会因为stop-the-world 机制而出现短暂的暂停,这个阶段主要任务仅仅只是标记出GC Roots能直接关联对象,一旦标记完成之后,就会恢复之前被暂停的所有线程。直接关联对象比较小,所以这里的速度非常快。
- 并发标记阶段:从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程比较耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行。
- 重新标记阶段:由于在并发标记阶段中,程序的工作线程会和垃圾收集线程同时运行或者交叉运行,因此为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间通常会比初始标记阶段稍长一些,但也远比并发标记阶段的时间短。
- 并发清除(Concurrent-Sweep)阶段:此阶段清理删除掉标记阶段判断的已经死亡的对象,释放内存空间。由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的
另外,由于在垃圾收集阶段用户线程没有中断,所以在CMS回收过程中,还应该确保应用程序用户线程有足够的内存可用。因此,CMS收集器不能像其他收集器那样等到老年代几乎完全被填满了再进行收集,而是当堆内存使用率达到某一阈值时,便开始进行回收,以确保应用程序在CMS工作过程中依然有足够的空间支持应用程序运行。要是CMS运行期间预留的内存无法满足程序需要,就会出现一次“Concurrent Mode Failure”失败,这时虚拟机将启动后备预案:临时启用serial old 收集器来重新进行老年代的垃圾收集,这样停顿时间就很长了。
3 CMS的利弊
CMS的优点
- 并发收集
- 低延迟.
CMS的弊端:
1)会产生内存碎片。CMS使用的是标记-清除算法,不会在垃圾收集后对内存进行调整,内存也会因此变得不规整。导致并发清除后,用户线程可用的空间不足。在无法分配大对象的情况下,不得不提前触发Full GC。
2 ) CMS收集器对CPU资源非常敏感。在并发阶段,它虽然不会导致用户停顿,但是为占用了一部分线程而导致应用程序变慢,总吞吐量会降低。
3 ) CMS收集器无法处理浮动垃圾。可能出现“concurrent Mode Failure"失败而导致另一次 Full GC 的产生。在并发标记阶段由于程序的工作线程和垃圾收集线程是同时运行或者交叉运行的,那么在并发标记阶段如果产生新的垃圾对象,CMS将无法对这些垃圾对象进行标记,最终会导致这些新产生的垃圾对象没有被及时回收,从而只能在下一次执行Gc时释放这些之前未被回收的内存空间。
4.参数设置
1.+UseConcMarkSweepGC:打开CMS垃圾收集器,因为是和ParGC配合使用的,所以也会默认打开年轻代收集器ParGC。
2…-XX: CMSInitiatingoccupanyFraction设置堆内存使用率的阈值,一旦达到该阈值,便开始进行回收。默认是92%,如果内存占用上升的慢,CMS会调高阈值。这样就可以减少CMS回收垃圾的次数。
3.-XX:+UseCMSCompactAtFullcollection用于指定在执行完FullGC后对内存空间进行压缩整理,以此避免内存碎片的产生。不过由于内存压缩整理过程无法并发执行,所带来的问题就是停顿时间变得更长了。
4.-XX:CMSFullGCsBeforeCompaction设置在执行多少次Full cC后对内存空间进行压缩整理。
5.-XX:ParallelCMSThread设置CMS的线程数量。