概述:

  1. 如果说GC回收算法是方法论,那么垃圾回收器就是落地实现。Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商、版本的虚拟机所提供的垃圾收集器都可能会有很大差别。

在介绍各种垃圾回收器之前介绍几个概念

吞吐量(Throughput)

吞吐量就是CPU用于运行用户代码的时间CPU总消耗时间的比值,即

吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间)。

假设用户代码 时间 99 分钟,垃圾回收 时间 1 分钟,那么吞吐量就是 99% 。

停顿时间

停顿时间 指垃圾回收器正在运行时,应用程序暂停时间。对于 独占回收器 而言,停顿时间可能会比较长。使用 并发回收器 时,由于垃圾回收器和应用程序 交替运行,程序的 停顿时间 会变短,但是,由于其 效率 很可能不如独占垃圾回收器,故系统的 吞吐量 可能会较低。

并行和并发

  • 串行(Parallel):单线程进行垃圾回收工作,但此时用户线程仍然处于等待状态。
  • 并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。
  • 并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序在继续运行。而垃圾收集程序运行在另一个CPU上。

    新生代GC(Minor GC)

    指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。

    老年代GC(Major GC)

    指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC(但非绝对的,在Parallel Scavenge收集器的收集策略里就有直接进行Major GC的策略选择过程)。Major GC的速度一般会比Minor GC慢10倍以上。

    垃圾收集器种类

    如下图所示,大致将垃圾收集器分为新生代和年老代。
    WX20191215-202037@2x.png

    新生代收集器

    Serial、ParNew、Parallel Scavenge

    老年代回收器

    Serial Old、Parallel Old、CMS

    整堆回收器

    G1
    **两种垃圾回收器之间有连线表示它们可以搭配使用,可选的搭配方案如下:
参数 新生代垃圾收集器 新生代算法 老年代垃圾收集器 老年代算法
-XX:UseSerialGC SerialGC 复制 SerialOldGC 标记整理
-XX:+UseParNewGC ParNew 复制 SerialOldGC 标记整理
-XX:+UseParallelGC/
-XX:+UseParallelOldGC
Parallel[Scavenge] 复制 ParallelOld 标记整理
-XX:+UseConcMarkSweepGC ParNew 复制 CMS+SerialOld收集器组合,SerialOld作为CMS出错备用收集器 标记清除
-XX:UseG1GC G1整体上用标-清算法 局部是复制算法,不会产生内存碎片
收集器 串行、并行or并发 新生代/老年代 目标 适用场景
Serial 串行 新生代 响应速度优先 单CPU环境下的Client模式
Serial Old 串行 老年代 响应速度优先 单CPU环境下的Client模式、CMS的后备预案
ParNew 并行 新生代 响应速度优先 多CPU环境时在Server模式下与CMS配合
Parallel Scavenge 并行 新生代 吞吐量优先 在后台运算而不需要太多交互的任务
Parallel Old 并行 老年代 吞吐量优先 在后台运算而不需要太多交互的任务
CMS 并发 老年代 响应速度优先 集中在互联网站或B/S系统服务端上的Java应用
G1 并发 both 响应速度优先 面向服务端应用,将来替换CMS