JVM之老年代垃圾收集器

446 阅读3分钟

「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战」。

引言:前文介绍了部分Java虚拟机新生代的垃圾收集器,于是今儿就介绍下部分老年代垃圾收集器。

老年代垃圾收集器

image.png

如上图,接下来我们要介绍的老年代垃圾收集器大致为CMS、Serial Old、Parallel Old收集器。

Serial Old垃圾收集器

Serial Old收集器是单线程收集器,并使用标记-整理算法,主要是提供给客户端下的HotSpot虚拟机使用。服务端模式下的话在JDK5之前是配合Parallel Scavenge收集器使用以及作为CMS收集器失败时的后备预案。

image.png

Parallel Old收集器

该收集器是Parallel Scavenge收集器的老年代版本,该收集器支持多线程并基于标记-整理算法实现。在注重吞吐量或者处理器资源比较稀缺的场合可以优先考虑Parallel Scavenge收集器加Parallel Old收集器的组合。其工作流程如下图所示:

image.png

CMS收集器

CMS收集器是一款以获取最短回收暂停时间为目标的收集器,很大一部分应用于互联网网站或者基于浏览器的B/S系统的服务端上,因为关注服务的响应速度,希望系统停顿时间尽可能短,以给用户较好的交互体验。

CMS收集器是基于标记-清除实现的,其过程分为四个阶段:

  • 初始标记:标记GC Root能直接关联到的对象,速度很快,但还是需要暂停用户线程

  • 并发标记:从GC Root的直接关联对象开始遍历整个对象图,这个过程很长不过不用暂停用户线程。

  • 重新标记:该阶段是为了修正并发标记阶段变动的标记。该阶段需要暂停用户线程

  • 并发清除:清理删除标记阶段的已经死亡的对象。

CMS收集器是一个并发低停顿收集器,不过其还存在以下三个缺点:

1.在并发阶段虽然不会暂停线程,但是其因为占用了一部分线程会导致应用程序变慢降低总吞吐量。虽然提供了增量式并发收集器的CMS收集器变种,也就是在并发标记和清理的时候让线程和用户线程交替运行,尽量减少垃圾收集线程独占资源的时间。

2.CMS收集器无法处理浮动垃圾(在CMS并发标记和并发清除阶段,用户进程运行时候产生的垃圾),还有就是垃圾收集阶段用户线程还要运行,所以需要预留一部分空间给用户线程使用。

3.因为CMS收集器是基于标记-清除算法的,这意味着收集结束会产生许多空间碎片,空间碎片过多会影响大对象的分配。