85.CMS 垃圾回收器可以详细说说吗?

85.CMS 垃圾回收器可以详细说说吗?

00:00
05:04

CMS 垃圾回收器主打的是低延迟,在JDK1.5时,Hotspot推出了强交互应用的垃圾收集器,也就是CMS收集器,全称Concurrent-Mark-Sweep。它是Hotspot虚拟机中第一款真正意义上的并发收集器,它第一次实现了垃圾收集线程与用户线程同时工作。

CMS收集器的关注点是尽可能缩短垃圾收集时用户线程的停顿时间。停顿时间越短(低延迟)就越适合与用户交互的程序,良好的响应速度能提升用户体验。CMS 垃圾收集器采用标记-清除算法并且也会有STW机制。

但是,CMS 垃圾收集器无法和JDK1.4中已经存在的新生代收集器Parallel Scavenge配合使用,所以JDK 1.5中使用CMS来收集老年代的时候,新生代只能选择ParNew或Serial收集器中的一个。

工作原理:

CMS整个过程比较复杂,分为4个主要阶段,即初始标记阶段、并发标记阶段、重新标记阶段和并发清除阶段。


初始标记阶段:在这个阶段中,程序所有工作线程都将会因为STW机制而出现短暂的暂停,这个阶段主要任务仅仅是标记出GC Roots能直接关联到的对象。一旦标记完成之后就会恢复之前被暂停的所有应用线程。由于直接关联对象比较小,所以这里速度非常快。


并发标记阶段:从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行。


重新标记阶段:由于在并发标记阶段中,程序的工作线程会和垃圾收集线程同时运行或者交叉运行,因此为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间通常会比初始标记阶段稍长一些,但也远比并发标记阶段的时间短。


并发清除阶段:这个阶段清理删除掉标记阶段判断的已经死亡的对象,释放空间。由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的。

尽管CMS收集器采用的是并发回收,但是在其初始化标记和再次标记这两个阶段中任需要执行STW机制来暂停程序中的工作线程,不过暂停时间不长;由于最耗费时间的并发标记与并发清除阶段都不需要暂停工作,所以整体的回收是低停顿的。此外,由于在垃圾收集阶段用户线程没有中断,所以在CMS回收过程中,还应该确保应用程序用户线程有足够的内存可用。因此,CMS收集器不能像其他收集器那样等到老年代几乎被完全填满再进行收集,而是当堆内存使用率达到某一阈值时,就开始进行回收,以确保应用程序在CMS工作过程中依然有足够的空间支持应用程序运行。要是CMS运行期间预留的内存无法满足程序需要,就会出现一次“Concurrent Mode Failure”失败,这时虚拟机将启动后备预案:临时启用Serial Old收集器来重新进行老年代的垃圾收集,这样停顿就长了。

CMS收集器的垃圾收集算法采用的是标记-清除算法,不可避免的会产生一些内存碎片。那么CMS在为新对象分配内存空间时,将无法使用指针碰撞技术,只能选择空闲列表执行内存分配。

JDK 9时,CMS被标记了将会弃用,到JDK14时,删除了CMS垃圾收集器。

总的来说,CMS收集器的优缺点。

优点:


并发收集


低延迟

缺点:


会产生内存碎片


CMS收集器对CPU资源非常敏感。


CMS收集器无法处理浮动垃圾。


以上内容来自专辑
用户评论

    还没有评论,快来发表第一个评论!