CMS回收器: 低延迟
- 在JDK1.5时期,HotSpot推出了一款在
强交互应用
中几乎可认为有划时代意义的垃圾收集器: CMS(Concurrent-Mark-Sweep)收集器,这款收集器是HotSpot虚拟机中第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程同时工作。
- CMS收集器的关注点是尽可能缩短垃圾收集时用户线程的停顿时间。停顿时间越短(低延迟)就越适合与用户交互的程序,良好的响应速度能提升用户体验。
-
目前很大一部分的Java应用几种在互联网站或者B/S系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间最短
,以给用户带来的较好的体验。CMS收集器就非常符合这类应用的需求。
-
- CMS的垃圾收集算法采用
标记-清除
算法,并且也会"Stop-the-world"。
不幸的是,CMS作为老年代的收集器,却无法与JDK1.4.0中已经存在的新生代收集器Parallel Scavenge配合工作,所以在JDK1.5中使用CMS来收集老年代的时候,新生代只能选择ParNew或者Serial收集器中的一个。
在G1出现之前,CMS使用还是非常广泛的。一直到今天,仍然有很多系统使用CMS GC。
CMS的工作原理
CMS整个过程比之前的收集器要复杂,整个过程分为4个主要阶段,即初始标记阶段、并发标记阶段、重新标记阶段和并发清除阶段。
- 初始标记(Initial-Mark)阶段: 在这个阶段中,程序中所有的工作线程都将会因为"Stop-the-World"机制而出现短暂的暂停,这个阶段的主要任务
仅仅只是标记出GC Roots能直接关联到的对象。
一旦标记完成之后就会恢复之前被暂停的所有应用线程。由于直接关联对象比较小,所以这里的速度非常快。
- 并发标记(Concurrent-Mark)阶段: 从GC Roots的
直接关联对象开始遍历整个对象图的过程
,这个过程耗时较长
但是不需要停顿用户线程
,可以与垃圾收集线程一起并发运行。 - 重新标记(Remark)阶段: 由于在并发标记阶段中,程序的工作线程会和垃圾收集线程同时运行或者交叉运行,因此为了
修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录
,这个阶段的停顿时间通常会比初始标记阶段稍长一些,但也远比并发标记阶段的时间短。 - 并发清除(Concurrent-Sweep)阶段: 此阶段
清理删除掉标记阶段判断的已经死亡的对象,释放内存空间
。由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的。