CMS收集器是基于标记-清除算法实现的。
它的垃圾收集分为四个步骤:
- 初始标记
- 并发标记
- 重新标记
- 并发清除
其中初始标记与重新标记过程需要Stop the World。
初始标记仅标记GC Roots直接关联的对象,速度很快;并发标记阶段则是从GC Roots直接关联的对象开始遍历整个对象图的过程;重新标记阶段是为了修正并发标记期间,用户线程继续运作而导致标记产生变动的那一部分对象标记记录,时间远比并发标记耗时短;并发清除阶段则是清除删掉标记阶段判断的已死亡的对象。
在耗时最长的并发标记以及并发清除阶段是用户线程并发运行的。
三个明显的缺点:
- 在处理器核心数量不足四个时,CMS占用过多的处理器资源,会导致应用程序变慢,降低总吞吐量。在这种情况下,曾尝试过“增量式并发收集器”,就是让用户线程与垃圾收集器线程抢占式运行,后被抛弃。
- 在并发标记与并发清除阶段因为用户线程还在运行,会有新的垃圾产生,这部分垃圾成为“浮动垃圾”。也因为用户线程仍在继续运行,那就需要预留足够的内存空间供用户线程使用,因此CMS收集器不能等到老年代几乎被填满了再进行收集,必须设定一个阈值。
- 标记-清除算法会造成空间碎片。