💎 G1 垃圾收集器工作模式全景解析:从日常快扫到紧急抢救(Young GC,Mix GC,Full GC)

52 阅读8分钟

🎯 导读:理解 G1 的“分治”哲学

G1 (Garbage-First) 收集器是现代 Java 应用的默认 GC,其核心思想是将整个堆内存划分为多个 Region,并进行分治管理。要用好 G1,必须理解它的三种主要工作模式。

本文将用最简单、最生动的语言,为你彻底剖析 G1 的三种 GC 模式:Young GC(日常整理)、Mixed GC(增量大扫除)和 Full GC(紧急抢救)。


👶 一、Young GC:新生代的日常快速整理

你可以把 Young GC 看作是 G1 收集器在新生代区域执行的**“日常快速清洁”**。它的目标是快速清理新产生的垃圾,为新对象腾出空间。

1. 触发时机:Eden 区空间耗尽与停顿预算评估 📈

Young GC 的触发机制非常智能,它将 “空间不足” 作为启动契机,但会以 “停顿预算” 作为最终决策依据:

  • 空间触发点: 应用程序创建新对象,导致 当前分配给 Eden 区的 Region 全部被占满,无法提供新的空闲 Region。

  • 预算评估机制(核心): 此时 G1 并不会立即执行 GC,而是基于历史数据进行评估:

    1. 预测耗时: G1 预测:如果现在就执行 Young GC 来清理当前的新生代区域,预计需要多久时间?

    2. 决策点:

      • 如果 预测耗时 远小于 -XX:MaxGCPauseMillis 设定的最大停顿时间。

        G1 决策: 此时新生代规模过小,停顿时间绰绰有余。G1 会增加新生代 Region 的数量(扩大 Eden 区) ,让应用线程继续分配对象,以提高吞吐量

      • 直到下一次 Eden 区放满,G1 预测的回收时间接近或超过 -XX:MaxGCPauseMillis 设定的值。

        G1 决策: 新生代规模已达到停顿预算的上限,必须立即触发 Young GC,以避免超时。

2. 工作机制:STW 暂停与并行复制

一旦 G1 决定执行 Young GC,它必须让应用程序暂停下来(Stop-The-World, STW),才能安全地进行清理。

  1. 强制暂停应用: 所有应用程序线程(Mutator)暂时停止。

  2. 筛选与标记: GC 线程并行地检查当前新生代区域(Eden 和 Survivor)中的存活对象

  3. 复制/晋升(核心动作): GC 将所有存活对象复制到堆中新的、空闲的 Region 里:

    • 年轻对象: 复制到新的 Survivor Region,年龄计数器加 1。
    • 年老对象/达到动态晋升年龄的对象: 直接复制到 老年代 Region
  4. 释放空间: 复制完成后,原来的 Eden 区和旧的 Survivor 区中的所有 Region 都会被清空,并重新标记为**“空闲”**,可以用于下一次对象分配。

3. Young GC 核心特点总结

特点含义
动态大小G1 会根据 -XX:MaxGCPauseMillis 动态调整新生代的大小,这是其智能化的核心。
只清理新生代不涉及老年代,因此 GC 速度非常快。
是 STW 停顿应用程序会停止,但由于动态预算,停顿时间高度可预测且受控
复制算法清理过程中会整理内存,消除内存碎片

🏗️ 二、Mixed GC:老年代的增量式大扫除

Mixed GC 是 G1 区别于其他收集器的核心。它的目标是分批次、有计划地回收老年代区域,避免老年代垃圾过多堆积。

1. 触发机制:并发标记完成

Mixed GC 的启动依赖于 并发标记周期 的完成:

  1. 老年代报警线: 当整个堆的占用率达到 IHOP 阈值(默认 45%)时,G1 启动并发标记
  2. 摸底排查(并发): G1 在应用运行的同时,计算出哪些老年代 Region 垃圾最多(这就是 Garbage-First 的由来)。
  3. 启动 Mixed GC: 并发标记结束后,G1 认为可以进行老年代回收,开始进入 Mixed GC 阶段。

2. 工作机制:预约停顿与增量清理

Mixed GC 并不是一次性清理老年代,而是多次 短暂停顿 的迭代过程。

  1. 停顿预算(MaxGCPauseMillis): G1 严格遵循用户设定的停顿时间预算。

  2. 圈定范围(CSet): G1 每次会从新生代垃圾占比最高的老年代 Region 中,圈定一个 Collection Set (CSet) 。圈定老年代 Region 的原则是:确保复制 CSet 中所有存活对象所需的时间,不会超出停顿预算

  3. STW 搬家与清理:

    • 暂停应用。
    • GC 线程并行地将 CSet 中所有的活对象(新生代和老年代)复制到新的空闲 Region
    • 释放 CSet 中所有旧的 Region。
  4. 循环迭代: G1 会连续进行 多次 类似的 短暂停顿 Mixed GC,逐步回收所有值得清理的老年代 Region。

3. Mixed GC 核心特点总结

特点含义
增量式回收老年代的回收工作被分散到多次短暂停顿中完成。
GC 范围新生代 + 部分老年代 Region。
可控停顿通过预测模型和 MaxGCPauseMillis,精确控制了单次 GC 的时长。

Mixed GC 的简单解释:分批搬家和预约停顿

你可以把 G1 堆内存想象成一个巨大的**“城市” ,而 老年代区域 就是城市里的一个个“旧小区”**,里面堆满了垃圾(死对象)和一些住户(活对象)。

Mixed GC 的目标: 不是一次性清空整个城市(那样会交通大瘫痪),而是分批次、有计划地拆除并整理这些旧小区,确保城市交通(应用运行)只受到短暂、可预测的影响。

阶段 1: 摸底排查(并发标记)

G1 怎么知道该清哪里?

  1. 摸底: G1 会在应用运行的同时(并发),偷偷地对所有旧小区进行**“垃圾普查”**。它会给每个小区打分:这个小区有多少垃圾?
  2. 排队: 普查结束后,垃圾最多(得分最高)的小区会被优先排队等待拆迁。

阶段 2: 预约停顿与选定范围(CSet Selection)

G1 如何确保停顿时间可控?

  1. 停顿预算: 你告诉 G1:“每次拆迁(GC),最多只能停顿 200 毫秒!”(-XX:MaxGCPauseMillis)。

  2. 圈定范围(CSet): G1 从排队的小区里,从垃圾最多的开始选。它会计算:“拆除这 5 个小区(Region),预计需要 180 毫秒,在预算内。就选它们了!”

    • 关键: Mixed GC 的范围是新生代 + 精选的老年代小区。
  3. STW 暂停: 确定好范围后,G1 宣布:“现在开始施工,应用线程暂停!”(STW Pause)。

阶段 3: 快速搬家与清理(增量式复制)

STW 期间 GC 做了什么?

  1. 快速搬家: GC 线程并行出动,把选定范围(CSet)里所有住户(活对象) ,快速复制到城市里的**新小区(新的 Region)**里。
  2. 清理旧址: 一旦所有住户搬走,旧小区(Region)就成了空地。G1 立即释放这些空地,城市可以重新在这里建新楼(分配新对象)。

阶段 4: 循环迭代(多次 Mixed GC)

一次拆迁不足以清空所有垃圾。

  • G1 会连续进行 多次 类似的 短暂停顿 Mixed GC,每次都根据停顿预算选择新的垃圾小区进行清理。
  • 当垃圾小区里的垃圾少到不值得拆迁(低于 5% 阈值)时,G1 就停止 Mixed GC,继续运行应用。

简单总结:

Mixed GC 就是一种**“短暂停顿、分批处理”**的老年代回收策略。它依靠前期的 并发标记 来选出垃圾最多的 Region,然后根据你设定的 停顿预算,每次只清理一部分 Region,从而将长时间的停顿分散成多次短暂的停顿。


💣 三、Full GC:系统崩溃前的紧急抢救

Full GC 是 G1 收集器的**“失败模式”**,是 G1 极力想要避免的情况。

1. 触发时机:并发回收彻底失败

Full GC 通常发生在以下唯一且灾难性的情况:

当 G1 的并发回收(Mixed GC 或 Young GC)速度,完全跟不上应用程序的内存分配速度时。

  • 场景: 应用线程分配对象太快,G1 来不及腾出新的空闲 Region,堆内存瞬间被用完。
  • 后果: G1 无法满足新的内存分配请求,JVM 只能触发 Full GC 来避免 内存溢出 (OOM)

2. 工作机制:最慢、最粗暴的整理

Full GC 是一种灾难性的回收模式:

  1. 强制停顿(STW): 立即停止所有应用程序线程,停顿时间极长
  2. 粗暴全扫: G1 放弃了并发优势,转而使用一个单线程、串行标记-清除-压缩 算法,完整扫描并整理整个堆
  3. 性能冲击: 停顿时间与堆内存大小成正相关。堆越大,停顿越久,完全打破了 G1 低延迟的承诺。

3. 为什么必须避免 Full GC?

  • 违背承诺: Full GC 直接导致 G1 的低延迟承诺失效
  • 性能调优信号: 如果你的应用经常出现 Full GC,说明 G1 配置(如堆大小、IHOP 阈值)存在严重问题,需要立即调优

✨ 总结:G1 三种模式的精要对比

G1 通过 Young GC 和 Mixed GC 的协同工作,将 GC 的停顿时间降到最低。

GC 类型目标区域停顿特点核心目的
Young GC新生代(Eden + Survivor)STW,但短暂停顿快速腾出新对象分配空间。
Mixed GC新生代 + 部分老年代STW,多次短暂停顿增量清理老年代垃圾,避免 Full GC。
Full GC整个堆STW,长时间停顿最后的抢救措施,极力避免发生。