7种分代垃圾收集器

常用匹配图

在这里插入图片描述
包括3种新生代专用,3种老年代专用和1种通用垃圾收集器
 

1.串行收集器(Serial)

  • Serial 收集器是Hotspot 运行在Client 模式下的默认新生代收集器
  • 只用一个 CPU(计算核心)/一条收集线程去完成 GC 工作, 且在进行垃圾收集时必须暂停其他所有的工作线程(“Stop The World” -后面简称 STW)
  • 使用-XX:+UseSerialGC 打开
  • 虽然是单线程收集, 但它却简单而高效, 在 VM 管理内存不大的情况下(收集几十 M~一两百 M 的新生代), 停顿时间完全可以控制在几十毫秒~一百多毫秒内
  • 工作过程:
    在这里插入图片描述
     

2.并行收集器(ParNew)

  • ParNew 收集器其实是前面 Serial 的多线程版本,使用多条线程进行 GC
  • 所有控制参数、收集算法、STW、对象分配规则、回收策略都与 Serial 完全一样
  • CMS 收集器的默认新生代收集器
  • 存在线程切换的开销, ParNew 在单 CPU 的环境中比不上 Serial, 且在通过超线程技术实现的两个 CPU 的环境中也不能 100%保证能超越 Serial
  • 但随着可用的 CPU 数量的增加, 收集效率肯定也会大大增加
  • ParNew 收集线程数与 CPU 的数量相同,可用-XX:ParallelGCThreads=参数控制 GC 线程数
  • 工作过程:在这里插入图片描述
     

3.Parallel Scavenge 收集器

  • 与 ParNew 类似, Parallel Scavenge 也是使用复制算法, 也是并行多线程收集器
  • 与其他收集器关注尽可能缩短垃圾收集时间不同, Parallel Scavenge 更关注系统吞吐量
  • 系统吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)
  • 高吞吐量适用于后台运算而不需要太多交互的任务,可以最高效率地利用CPU 时间,尽快地完成程序的运算任务
  • Parallel Scavenge 提供了如下参数设置系统吞吐量:
Parallel Scavenge参数 描述
-XX:MaxGCPauseMillis (毫秒数)收集器将尽力保证内存回收花费的时间不超过设定值, 但如果太小将会导致 GC 的频率增加
-XX:GCTimeRatio (整数:0 < GCTimeRatio < 100) 垃圾收集时间占总时间的比率
-XX:+UseAdaptiveSizePolicy 启用 GC 自适应的调节策略, VM 会根据当前系统的运行情况收集性能监控信息, 动态调整这些参数以提供最大的吞吐量

4.Serial Old 收集器

  • Serial Old 是Serial 收集器的老年代版本, 同样是单线程收集器
  • 使用“标记-整理”算法
  • 工作过程:在这里插入图片描述
     

5.Parallel Old 收集器

  • Parallel Scavenge 收集器的老年代版本
  • 使用多线程和“标记-整理”算法, 吞吐量优先
  • 与 Parallel Scavenge 配合在注重吞吐量的系统内使用
  • 工作过程:
    在这里插入图片描述
     

6.CMS 收集器(Concurrent Mark Sweep)

  • CMS(Concurrent Mark Sweep)收集器是一款真正意义上的并发收集器,
  • CMS 是一种以获取最短回收停顿时间为目标的收集器,又称多并发低暂停收集器
  • 使用-XX: +UseConcMarkSweepGC 打开
  • 基于”标记-清除”算法实现

整个 GC 过程分为以下 4 个步骤:

1.初始标记(CMS initial mark)
2.并发标记(CMS concurrent mark: GC Roots Tracing过程)
3.重新标记(CMS remark)
4.并发清除(CMS concurrent sweep: 已死对象将会就地释放)

  • 其中 1,3 两个步骤(初始标记、重新标记)仍需 STW
  • 初始标记仅只标记一下 GC Roots 能直接关联到的对象, 速度很快
  • 重新标记是为了修正并发标记期间因用户程序继续运行而导致产生变动的那一部分对象的标记记录
  • 工作过程:在这里插入图片描述

CMS 特点:

  • CMS 默认启动的回收线程数=(CPU 数目+3)/4
    • 当 CPU 数>4 时, GC 线程一般占用不超过 25%的 CPU 资源
    • 但是当 CPU 数<=4 时, GC 线程可能就会过多的占用用户 CPU 资源
       
  • 无法处理浮动垃圾, 可能导致另一次 Full GC 的产生
    • 浮动垃圾是指在 CMS 并发清理阶段用户线程运行而产生的新垃圾
    • 由于在 GC 阶段用户线程还需运行, 因此还需要预留足够的内存空间给用户线程使用, 导致 CMS 不能像其他收集器那样等到老年代几乎填满了再进行收集
    • CMS 提供了 -XX:CMSInitiatingOccupancyFraction 参 数 来 **设 置 GC 的 触 发 百 分 比 **( 以 及-XX:+UseCMSInitiatingOccupancyOnly 来启用该触发百分比)
    • 当 CMS 运行期间预留的内存无法满足程序需要, 就会出现 Promotion Failure 失败, 这时 VM 将启动后备预案: 临时启用 Serial Old 收集器来重新执行Full GC
    • CMS 通常配合大内存使用, 一旦大内存转入串行的Serial GC, 那停顿的时间就是大家都不愿看到的了
  • 由于 CMS 采用”标记-清除”算法实现, 可能会产生大量内存碎片,内存碎片过多可能会导致无法分配大对象而提前触发Full GC
    • 因此 CMS 提供了 -XX:+UseCMSCompactAtFullCollection 开关参数, 用于在 Full GC 后再执行一个碎片整理过程
    • 内存整理是无法并发的, 内存碎片问题虽然没有了, 但停顿时间也因此变长了
    • 因此 CMS 还提供了另外一个参数 -XX:CMSFullGCsBeforeCompaction 用于设置在执行 N 次不进行内存整理的 Full GC 后, 跟着来一次带整理(默认为 0: 每次进入 Full GC 时都进行碎片整理)
       

G1 收集器

  • G1(Garbage-First)是一款面向服务端应用的收集器, 主要目标用于配备多颗 CPU 的服务器治理大内存
    • G1计划作为并CMS的长期替代产品
    • -XX:+UseG1GC 启用 G1 收集器
  • G1 将整个 Java 堆划分为多个大小相等的独立区域(Region), 虽然还保留有新生代和老年代的概念, 但新生代和老年代不再是物理隔离的了, 它们都是一部分 Region(不需要连续)的集合,如:
    在这里插入图片描述
    • 每块区域既有可能属于 O 区、也有可能是 Y 区, 因此不需要一次就对整个老年代/新生代回收
    • 虽然在清理这些区块时 G1 仍然需要暂停应用线程, 但可以用相对较少的时间优先回收垃圾较多的 Region,保证G1在有限的时间内获取尽可能高的收集效率
  • G1 的新生代收集跟ParNew 类似: 存活的对象被转移到一个/多个Survivor Regions. 如果存活时间达到阀值, 这部分对象就会被提升到老年代.如图:
    在这里插入图片描述
    在这里插入图片描述
发布了48 篇原创文章 · 获赞 0 · 访问量 1025

猜你喜欢

转载自blog.csdn.net/qq_35764106/article/details/104061208