经典垃圾收集器

image.png

Serial收集器

最基础、历史最悠久的收集器。该收集器为单线程且在进行垃圾收集时,必须暂停其他所有工作线程、直至收集结束。
但它依然是HotSpot虚拟机运行在客户端模式下的默认新生代收集器。优点为简单而高效,是所有额外内存消耗最小的。在收集几十兆甚至一两百兆的新生代,垃圾收集的停顿时间完全可以控制在十几、几十毫秒内,这对于用户是完全可以接受的,所以Serial 收集器对于运行在客户端模式下的虚拟机来说是一个很好的选择。
image.png

ParNew收集器

ParNew 收集器实质上是 Serial 收集器的多线程并行版本,除了同时使用多条线程 进行垃圾收集之外,其余的行为包括 Serial 收集器可用的所有控制参数(例如:去X: SurvivorRatio、 -XX:PretenureSizeThreshold、去X:HandlePromotionFailure 等)、收集算法、 Stop The World、对象分配规则、回收策略等都与 Serial 收集器完全一致,在实现上这两种 收集器也共用了相当多的代码。
它是Server端的收集器,在JDK7之前首选的新生代收集器,原因是除了Serial收集器以外,目前只有它能与CMS收集器配合工作。
image.png

Parallel Scavenge 收集器

Parallel Scavenge收集器也是一款新生代收集器,它同样是基于标记 一 复制算法实现的收集器。
该收集器侧重于达到一个可控制的吞吐量,Parallel Scavenge 收集器也经常被称作“吞吐量优先收集器” 。
Parallel Scavenge 收集器关注点是吞吐量(高效率的利用 CPU)。CMS 等垃圾收集器的关注点更多的是用户线程的停顿时间(提高用户体验)。所谓吞吐量就是 CPU 中用于运行用户代码的时间与 CPU 总消耗时间的比值。 Parallel Scavenge 收集器提供了很多参数供用户找到最合适的停顿时间或最大吞吐量,如果对于收集器运作不太了解的话,手工优化存在困难的话可以选择把内存管理优化交给虚拟机去完成也是一个不错的选择。
image.png
Parallel Scavenge 收集器还有一个参数 -XX:+UseAdaptiveSizePolicy 值得我们关注。 这是一个开关参数,用来打开垃圾收集的自适应的调节策略( GC Ergonomics),当这个参数被激活之后,就不需要人工指定新生代的 大小(-Xmn)、 Eden 与 Survivor 区的比例 (XX:SurvivorRatio)、 晋升老年代对象大小(-XX:PretenureS izeThreshold)等细节参数了, 虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量。

Serial Old收集器

Serial Old是Serial收集器的老年代版本,单线程收集器,使用标记-整理法,也是给Client场景下使用。如果在Server场景下,主要有两大用途:

  • 一种是在 JDK 5 以及之前的版本中与 Parallel Scavenge 收集 器搭配使用。
  • 另外一种就是作为 CMS 收集器发生失败时的后备预案,在并发收集发生 Concurrent Mode Failure 时使用。

image.png

Parallel Old 收集器

Parallel Old 是 Parallel Scavenge 收集器的老年代版本, 支持多线程并发收集,基于 标记 - 整理算法实现。
在注重吞吐量或者处理器资源较为稀缺的场合,都可以优先考虑 Parallel Scavenge 加 Parallel Old 收集器这个组合。
image.png

CMS收集器

CMS ( Concurrent Mark Sweep) 收集器是一种以获取最短回收停顿时间为目标的收集器。基于标记-清除算法实现。过程共分为4步:

  1. 初始标记:简单标记一下GC Roots能直接关联到的对象,速度很快,需要暂停用户线程。
  2. 并发标记:从GC Roots直接关联的对象开始遍历整个对象图的过程,这个耗时长,不需要暂停用户线程。
  3. 重新标记:修正并发标记期间,因用户程序继续运作导致标记产生变动的那一部分对象的标记记录,需要暂停。
  4. 并发清除:清除标记的对象,不需要暂停。

image.png
缺点:

  1. 消耗处理器运算资源,对于处理器核心数量较少或性能不强的情况会导致程序的执行速度忽然大幅降低。
  2. 无法处理浮动垃圾,可能出现并发失败(Concurrent Mode Failure,这时虚拟机启动后备预案:冻结用户线程,临时启动Serial Old 收集器来重新进行老年代的垃圾收集)。
    浮动垃圾是在并发标记和并发清理阶段,因为用户线程继续运行而产生的垃圾,这部分只能等到下一次GC时才能进行回收。
    因此需要预留一些空间给用户线程使用,如果预留的空间不够存放浮动垃圾,则Concurrent Mode Failure
  3. 标记-清除算法导致的空间碎片,无法找到连续的空间来分配较大的对象,不得不触发一次Full GC。

    Garbage First收集器

    该收集器也称为G1,是一款面向服务端应用的垃圾收集器,其收集的范围是整个新生代或老年代,主要针对配备多颗处理器以及大容量内存的机器,大概率能够满足GC停顿时间的同时,还能具备高吞吐量性能特征。
    G1的特点在于可预测停顿:G1除了像CMS追求低停顿外,可能建立可预测的停顿时间模型,G1将堆内存划分为固定大小的多个区域,称作Region。G1之所以能建立可预测停顿时间模型,是因为它跟踪各个Region的回收价值,并维护一个优先级列表,根据用户设定允许的收集停顿时间,优先处理回收价值最大的那些Region,保证在有限的时间内获取尽可能高的收集效率。
    如果不计算维护记忆集的操作,G1收集器的运作大致可划分为:

  4. 初始标记:简单标记下GC Roots能直接关联到的对象,并修改TAMS指针,为并发标记中正确的为出现的新对象分配Region。需暂停,但耗时短。

  5. 并发标记:进行可达性分析,递归扫描整个堆的对象图。耗时长,但可与用户程序并发执行。
  6. 最终标记:为了修正正在并发标记期间用户程序继续运作而导致标记产生变动的那一部分标记记录。这部分需要暂停用户程序,可并行执行。
  7. 筛选回收:对各个Region中的回收价值和成本进行排序,根据用户期望的GC停顿时间来制定回收计划。该回收涉及到存活对象的移动。