jvm常见垃圾回收器

七种垃圾回收器概述

JVM 中,具体实现有 SerialParNewParallelScavengeCMSSerialOld(MSC)ParallelOldG1 等。

如果当 垃圾回收器 进行垃圾清理时,必须 暂停 其他所有的 工作线程,直到它完全收集结束。我们称这种需要暂停工作线程才能进行清理的策略为 Stop-the-World。以上回收器中, SerialParNewParallelScavengeSerialOldParallelOld 均采用的是 Stop-the-World 的策略。

图中有 7 种不同的 垃圾回收器,它们分别用于不同分代的垃圾回收。

  • 新生代回收器:Serial、ParNew、Parallel Scavenge
  • 老年代回收器:Serial Old、Parallel Old、CMS
  • 整堆回收器:G1

单线程垃圾回收器

Serial(-XX:+UseSerialGC)

Serial 回收器是最基本的 新生代 垃圾回收器,是 单线程 的垃圾回收器。由于垃圾清理时, Serial 回收器 不存在 线程间的切换,因此,特别是在单 CPU 的环境下,它的 垃圾清除效率 比较高。对于 Client 运行模式的程序,选择 Serial 回收器是一个不错的选择。

Serial 新生代回收器 采用的是 复制算法

Serial Old(-XX:+UseSerialGC)

SerialOld 回收器是 Serial 回收器的 老生代版本,属于 单线程回收器,它使用 标记-整理 算法。对于 Server 模式下的虚拟机,在 JDK1.5 及其以前,它常与 ParallelScavenge 回收器配合使用,达到较好的 吞吐量,另外它也是 CMS回收器在 ConcurrentModeFailure 时的 后备方案

Serial 回收器和 SerialOld 回收器的执行效果如下:

SerialOld 老年代回收器 采用的是 标记 - 整理算法

多线程垃圾回收器

ParNew(-XX:+UseParNewGC)

ParNew 回收器是在 Serial 回收器的基础上演化而来的,属于 Serial 回收器的 多线程版本,同样运行在 新生代区域。在实现上,两者共用很多代码。在不同运行环境下,根据 CPU 核数,开启 不同的线程数,从而达到 最优 的垃圾回收效果。对于那些 Server 模式的应用程序,如果考虑采用 CMS 作为 老生代回收器时, ParNew 回收器是一个不错的选择。

ParNew 新生代回收器 采用的是 复制算法

Parallel Scavenge(-XX:+UseParallelGC)

ParNew 回收一样, ParallelScavenge 回收器也是运行在 新生代区域,属于 多线程 的回收器。但不同的是, ParNew 回收器是通过控制 垃圾回收线程数来进行参数调整,而 ParallelScavenge 回收器更关心的是 程序运行的吞吐量。即一段时间内,用户代码 运行时间占 总运行时间 的百分比。

ParallelScavenge 新生代回收器 采用的是 复制算法

Parallel Old(-XX:+UseParallelOldGC)

ParallelOld 回收器是 ParallelScavenge 回收器的 老生代版本,属于 多线程回收器,采用 标记-整理算法ParallelOld 回收器和 ParallelScavenge回收器同样考虑了 吞吐量优先 这一指标,非常适合那些 注重吞吐量CPU 资源敏感的场合。

ParallelOld 老年代回收器 采用的是 标记 - 整理算法

其他的回收器

CMS(-XX:+UseConcMarkSweepGC)

CMS(ConcurrentMarkSweep) 回收器是在 最短回收停顿时间 为前提的回收器,属于 多线程回收器,采用 标记-清除算法

G1回收器(垃圾区域Region优先)

G1JDK1.7 中正式投入使用的用于取代 CMS压缩回收器。它虽然没有在物理上隔断 新生代老生代,但是仍然属于 分代垃圾回收器G1 仍然会区分 年轻代老年代,年轻代依然分有 Eden 区与 Survivor 区。

G1 首先将 分为 大小相等Region,避免 全区域 的垃圾回收。然后追踪每个 Region 垃圾 堆积的价值大小,在后台维护一个 优先列表,根据允许的回收时间优先回收价值最大的 Region。同时 G1采用 RememberedSet 来存放 Region之间的 对象引用 ,其他回收器中的 新生代老年代 之间的对象引用,从而避免 全堆扫描