java垃圾回收CMS收集器

CMS(Concurrent Mark Sweep)收集器是一种以最短回收停顿时间为目标的收集器。目前很大一部分的java应用集中在互联网站或者B/S系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间最短,已给用户带来较好的体验。CMS收集器就非常符合这类应用的需求。

从名字(包含 Mark Sweep)上就可以看出,CMS收集器是基于“标记-清除”算法实现的,整个过程分为4步包括:

1、初始标记(CMS initial mark)

2、并发标记(CMS concurrent mark)

3、重新标记(CMS remark)

4、并发清除(CMS concurrent sweep)

其中,初始标记、重新标记这两个步骤仍然需要“stop the word”。初始标记仅仅只是标记一下GC roots能直接关联到的对象,速度很快,并发标记阶段就是进行GC Roots Tracing的过程,而重新标记阶段是为了修正并发标记期间因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长,但远比并发标记的时间短。由于整个过程耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作,所以,从整体上来说,CMS收集器的内存回收过程是与用户线程一起并发执行的。如下图


CMS收集器运行示意图

CMS是一款优秀的收集器,它的主要优点是并发收集、低停顿。但是还远达不到完美的成都,它的主要缺点如下:

1、CMS收集器对资源非常敏感。总的来说面向并发设计的程序都对CPU资源比较敏感。在并发阶段,他虽然不会导致应用程序线程停顿,但是会因为占用了一部分线程(或说CPU资源)而导致应用程序变慢,总吞吐量降低。

2、CMS收集器无法处理浮动垃圾,可能出现“Concurrent Mode Failure”失败而导致另一次Full GC产生。由于CMS并发清理阶段用户线程还在运行着,伴随程序运行自然就还会有新的垃圾不断产生,这部分垃圾出现在标记过程之后,CMS无法在当次收集中处理掉他们,只好留待下一次GC在清理。这部分垃圾被称为浮动垃圾。

3、CMS收集器是基于“标记-清除”算法实现的收集器,着意味着收集结束时会有大量空间碎片产生。空间碎片多的情况可能会出现还有很大的空间但是无法找到足够大的连续空间来分配对象,不得不提前触发一次Full GC。为了解决这个问题CMS收集器会在顶不住了要进行Full GC时开启内存碎片合并整理过程,此过程无法并发,会导致停顿时间变长。

你可能感兴趣的:(java垃圾回收CMS收集器)