🎯 导读:理解 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,而是基于历史数据进行评估:
-
预测耗时: G1 预测:如果现在就执行 Young GC 来清理当前的新生代区域,预计需要多久时间?
-
决策点:
-
如果 预测耗时 远小于
-XX:MaxGCPauseMillis设定的最大停顿时间。G1 决策: 此时新生代规模过小,停顿时间绰绰有余。G1 会增加新生代 Region 的数量(扩大 Eden 区) ,让应用线程继续分配对象,以提高吞吐量。
-
直到下一次 Eden 区放满,G1 预测的回收时间接近或超过
-XX:MaxGCPauseMillis设定的值。G1 决策: 新生代规模已达到停顿预算的上限,必须立即触发 Young GC,以避免超时。
-
-
2. 工作机制:STW 暂停与并行复制
一旦 G1 决定执行 Young GC,它必须让应用程序暂停下来(Stop-The-World, STW),才能安全地进行清理。
-
强制暂停应用: 所有应用程序线程(Mutator)暂时停止。
-
筛选与标记: GC 线程并行地检查当前新生代区域(Eden 和 Survivor)中的存活对象。
-
复制/晋升(核心动作): GC 将所有存活对象复制到堆中新的、空闲的 Region 里:
- 年轻对象: 复制到新的 Survivor Region,年龄计数器加 1。
- 年老对象/达到动态晋升年龄的对象: 直接复制到 老年代 Region。
-
释放空间: 复制完成后,原来的 Eden 区和旧的 Survivor 区中的所有 Region 都会被清空,并重新标记为**“空闲”**,可以用于下一次对象分配。
3. Young GC 核心特点总结
| 特点 | 含义 |
|---|---|
| 动态大小 | G1 会根据 -XX:MaxGCPauseMillis 动态调整新生代的大小,这是其智能化的核心。 |
| 只清理新生代 | 不涉及老年代,因此 GC 速度非常快。 |
| 是 STW 停顿 | 应用程序会停止,但由于动态预算,停顿时间高度可预测且受控。 |
| 复制算法 | 清理过程中会整理内存,消除内存碎片。 |
🏗️ 二、Mixed GC:老年代的增量式大扫除
Mixed GC 是 G1 区别于其他收集器的核心。它的目标是分批次、有计划地回收老年代区域,避免老年代垃圾过多堆积。
1. 触发机制:并发标记完成
Mixed GC 的启动依赖于 并发标记周期 的完成:
- 老年代报警线: 当整个堆的占用率达到 IHOP 阈值(默认 45%)时,G1 启动并发标记。
- 摸底排查(并发): G1 在应用运行的同时,计算出哪些老年代 Region 垃圾最多(这就是 Garbage-First 的由来)。
- 启动 Mixed GC: 并发标记结束后,G1 认为可以进行老年代回收,开始进入 Mixed GC 阶段。
2. 工作机制:预约停顿与增量清理
Mixed GC 并不是一次性清理老年代,而是多次 短暂停顿 的迭代过程。
-
停顿预算(MaxGCPauseMillis): G1 严格遵循用户设定的停顿时间预算。
-
圈定范围(CSet): G1 每次会从新生代和垃圾占比最高的老年代 Region 中,圈定一个 Collection Set (CSet) 。圈定老年代 Region 的原则是:确保复制 CSet 中所有存活对象所需的时间,不会超出停顿预算。
-
STW 搬家与清理:
- 暂停应用。
- GC 线程并行地将 CSet 中所有的活对象(新生代和老年代)复制到新的空闲 Region。
- 释放 CSet 中所有旧的 Region。
-
循环迭代: G1 会连续进行 多次 类似的 短暂停顿 Mixed GC,逐步回收所有值得清理的老年代 Region。
3. Mixed GC 核心特点总结
| 特点 | 含义 |
|---|---|
| 增量式回收 | 老年代的回收工作被分散到多次短暂停顿中完成。 |
| GC 范围 | 新生代 + 部分老年代 Region。 |
| 可控停顿 | 通过预测模型和 MaxGCPauseMillis,精确控制了单次 GC 的时长。 |
Mixed GC 的简单解释:分批搬家和预约停顿
你可以把 G1 堆内存想象成一个巨大的**“城市” ,而 老年代区域 就是城市里的一个个“旧小区”**,里面堆满了垃圾(死对象)和一些住户(活对象)。
Mixed GC 的目标: 不是一次性清空整个城市(那样会交通大瘫痪),而是分批次、有计划地拆除并整理这些旧小区,确保城市交通(应用运行)只受到短暂、可预测的影响。
阶段 1: 摸底排查(并发标记)
G1 怎么知道该清哪里?
- 摸底: G1 会在应用运行的同时(并发),偷偷地对所有旧小区进行**“垃圾普查”**。它会给每个小区打分:这个小区有多少垃圾?
- 排队: 普查结束后,垃圾最多(得分最高)的小区会被优先排队等待拆迁。
阶段 2: 预约停顿与选定范围(CSet Selection)
G1 如何确保停顿时间可控?
-
停顿预算: 你告诉 G1:“每次拆迁(GC),最多只能停顿 200 毫秒!”(
-XX:MaxGCPauseMillis)。 -
圈定范围(CSet): G1 从排队的小区里,从垃圾最多的开始选。它会计算:“拆除这 5 个小区(Region),预计需要 180 毫秒,在预算内。就选它们了!”
- 关键: Mixed GC 的范围是新生代 + 精选的老年代小区。
-
STW 暂停: 确定好范围后,G1 宣布:“现在开始施工,应用线程暂停!”(STW Pause)。
阶段 3: 快速搬家与清理(增量式复制)
STW 期间 GC 做了什么?
- 快速搬家: GC 线程并行出动,把选定范围(CSet)里所有的住户(活对象) ,快速复制到城市里的**新小区(新的 Region)**里。
- 清理旧址: 一旦所有住户搬走,旧小区(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 是一种灾难性的回收模式:
- 强制停顿(STW): 立即停止所有应用程序线程,停顿时间极长。
- 粗暴全扫: G1 放弃了并发优势,转而使用一个单线程、串行的 标记-清除-压缩 算法,完整扫描并整理整个堆。
- 性能冲击: 停顿时间与堆内存大小成正相关。堆越大,停顿越久,完全打破了 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,长时间停顿 | 最后的抢救措施,极力避免发生。 |