目录
[一、G1 的核心设计基础](#一、G1 的核心设计基础)
[1. 堆内存的 Region 化划分(逻辑分区,动态标记)](#1. 堆内存的 Region 化划分(逻辑分区,动态标记))
[2. 垃圾优先回收策略(核心设计目标)](#2. 垃圾优先回收策略(核心设计目标))
[3. 核心回收算法(无内存碎片,兼顾效率)](#3. 核心回收算法(无内存碎片,兼顾效率))
[4. 前置概念:GC Roots 与跨代引用管理](#4. 前置概念:GC Roots 与跨代引用管理)
[二、G1 的完整工作流程(三类 GC,分层执行)](#二、G1 的完整工作流程(三类 GC,分层执行))
[流程 1:Young GC(新生代回收)------ 高频、短停顿、纯 STW](#流程 1:Young GC(新生代回收)—— 高频、短停顿、纯 STW)
[1. 触发条件](#1. 触发条件)
[2. 完整执行步骤(多线程并行,全程 STW,毫秒级)](#2. 完整执行步骤(多线程并行,全程 STW,毫秒级))
[3. 关键特点](#3. 关键特点)
[流程 2:Mixed GC(混合回收)------ 核心流程、可预测停顿、部分并发 + 部分 STW](#流程 2:Mixed GC(混合回收)—— 核心流程、可预测停顿、部分并发 + 部分 STW)
[1. 触发条件](#1. 触发条件)
[2. 完整执行步骤(4 个阶段:2 个 STW+2 个并发,停顿可控)](#2. 完整执行步骤(4 个阶段:2 个 STW+2 个并发,停顿可控))
[阶段 1:初始标记(Initial Mark)------ STW,极短(复用 Young GC 的 STW)](#阶段 1:初始标记(Initial Mark)—— STW,极短(复用 Young GC 的 STW))
[阶段 2:并发标记(Concurrent Mark)------ 纯并发,不 STW,耗时最长](#阶段 2:并发标记(Concurrent Mark)—— 纯并发,不 STW,耗时最长)
[阶段 3:最终标记(Final Mark)------ STW,短时间](#阶段 3:最终标记(Final Mark)—— STW,短时间)
[阶段 4:筛选回收(Live Data Counting and Evacuation)------ STW,核心优化,停顿可预测](#阶段 4:筛选回收(Live Data Counting and Evacuation)—— STW,核心优化,停顿可预测)
[3. 关键特点](#3. 关键特点)
[流程 3:Full GC(兜底回收)------ 极少触发、长时间 STW、需彻底避免](#流程 3:Full GC(兜底回收)—— 极少触发、长时间 STW、需彻底避免)
[1. 触发条件](#1. 触发条件)
[2. 执行逻辑](#2. 执行逻辑)
[3. 关键特点](#3. 关键特点)
[三、G1 的核心工作联动逻辑](#三、G1 的核心工作联动逻辑)
[四、G1 的核心优化机制(对比 CMS,全维度升级)](#四、G1 的核心优化机制(对比 CMS,全维度升级))
[五、G1 核心配置参数](#五、G1 核心配置参数)
G1(Garbage-First)是 JDK9 + 默认的整堆低延迟垃圾收集器 ,核心设计目标是在大内存场景下实现可预测的 GC 停顿时间 ,同时兼顾吞吐量。它打破了传统 GC「新生代 + 老年代物理划分」的模式,采用Region 化整堆管理 ,结合并发标记、复制回收、垃圾优先筛选三大核心技术,自身实现新生代 + 老年代的全堆回收,彻底解决了 CMS 的内存碎片、并发失败等问题。
G1 的工作核心围绕Region 内存管理 + 三类分层 GC 流程(Young GC/Mixed GC/Full GC)展开,其中 Mixed GC是 G1 的设计精髓,也是实现停顿可预测的关键;Full GC 为兜底场景,生产中几乎不会触发。
一、G1 的核心设计基础
G1 的所有工作流程都基于Region 化堆内存管理 和垃圾优先回收策略,这是它与经典 GC(CMS/Parallel)最本质的区别,也是理解其工作原理的前提。
1. 堆内存的 Region 化划分(逻辑分区,动态标记)
G1 将整个 Java 堆划分为多个大小相等的独立内存块(Region),替代了传统 GC 的新生代、老年代物理分区,核心特点:
-
Region 大小统一 :默认 1MB~32MB(2 的幂次),JVM 会根据堆总大小自适应调整 (如堆 16G 则 Region 为 4M/8M),可通过
-XX:G1HeapRegionSize手动指定; -
类型动态标记 :每个 Region 无固定的代别,可动态标记 为不同类型,运行中可相互转换,核心类型包括:
Region 类型 核心作用 对应传统区域 Eden 存储新创建的普通对象 新生代 Eden 区 Survivor 存储 Young GC 后的存活对象 新生代 Survivor 区 Old 存储新生代晋升的长命对象、大对象 老年代 Humongous 存储超大对象(超过 Region 大小 50%),由连续多个 Region 组成 老年代大对象区 Free 空闲 Region,用于分配新对象或复制存活对象 无 -
逻辑分代 :G1 通过 Region 类型标记实现逻辑上的新生代 / 老年代,而非物理隔离,新生代由所有 Eden+Survivor Region 组成,老年代由所有 Old+Humongous Region 组成,占比可动态调整(新生代 5%~60%)。
2. 垃圾优先回收策略(核心设计目标)
G1 的「Garbage-First」体现在优先回收垃圾比例最高的 Region,核心逻辑:
- 每次回收前,G1 会统计每个 Region 的垃圾比例(垃圾占比 = 1 - 存活对象占比);
- 按垃圾比例从高到低为 Region 排序,形成回收候选列表;
- 结合用户指定的最大停顿时间 (
-XX:MaxGCPauseMillis,默认 200ms),计算可回收的 Region 数量(垃圾比例越高,回收效率越高,优先选择); - 仅回收筛选后的 Region,保证总 GC 停顿时间不超过阈值。
这一策略让 G1 在有限的 STW 时间内释放最多的内存 ,实现了停顿时间的可预测性,也是 G1 适配大内存(8G~64G)的关键。
3. 核心回收算法(无内存碎片,兼顾效率)
G1 全程采用复制算法完成垃圾回收,替代了 CMS 的标记 - 清除算法,核心特点:
- 回收时,将待回收 Region 中的存活对象 复制到空闲的 Free Region;
- 复制完成后,清空原 Region 并标记为 Free,用于后续对象分配;
- 最终存活对象会被集中存储在连续的 Region 中 ,无任何内存碎片,彻底解决了 CMS 的大对象分配失败问题。
4. 前置概念:GC Roots 与跨代引用管理
G1 通过 **SATB(Snapshot-At-The-Beginning,开始快照)机制管理跨代引用(如老年代对象引用新生代对象),配合卡表(Card Table)** 记录引用变动,避免全堆扫描,大幅降低 GC 开销,这一机制会在并发标记阶段核心使用。
二、G1 的完整工作流程(三类 GC,分层执行)
G1 的 GC 流程分为Young GC(新生代回收) 、Mixed GC(混合回收) 、Full GC(兜底回收)三类,三者为分层执行关系:
- Young GC:高频基础流程,仅回收新生代 Region,毫秒级 STW,是 G1 最常触发的 GC;
- Mixed GC :核心流程,替代传统 Major GC/Full GC,同时回收新生代所有 Region + 部分老年代 Region,部分并发 + 部分 STW,停顿时间可控;
- Full GC:兜底异常流程,仅在 Mixed GC 无法释放足够内存时触发,单线程 STW,生产中需彻底避免。
流程 1:Young GC(新生代回收)------ 高频、短停顿、纯 STW
G1 的 Young GC 与经典新生代 GC(ParNew)核心逻辑一致,仅回收所有 Eden Region + 非空 Survivor Region,基于 Region 粒度采用复制算法,是 G1 最常触发的 GC(每秒数次)。
1. 触发条件
Eden Region 内存不足,无法为新创建的普通对象分配内存(与传统 Young GC 触发条件完全一致,是程序运行的自然结果)。
2. 完整执行步骤(多线程并行,全程 STW,毫秒级)
G1 的 Young GC 为纯 STW 操作,但多线程并行执行,停顿时间极短,步骤如下:
- 暂停所有用户线程(STW):触发 Young GC 时,立即暂停所有业务线程,避免引用关系变动;
- 标记新生代 GC Roots :遍历虚拟机栈、本地方法栈等,标记新生代的 GC Roots ,同时通过卡表 标记老年代指向新生代的跨代引用(这是新生代存活对象的 "入口");
- 复制存活对象 :采用复制算法,将所有 Eden Region + 非空 Survivor Region 中的存活对象,复制到空闲的 Free Region :
- 年龄未达晋升阈值的对象 → 复制到新的 Survivor Region;
- 年龄达阈值(默认 15,
-XX:MaxTenuringThreshold)的对象 → 复制到Old Region;
- 重置 Region 状态 :清空原 Eden/Survivor Region,将其标记为Free Region,用于后续新对象分配;
- 恢复用户线程:完成所有操作后,恢复业务线程,Young GC 结束。
3. 关键特点
- 触发频率极高(程序运行中持续触发),但 STW 时间毫秒级(通常<50ms),对业务几乎无感知;
- 回收后无内存碎片,新生代 Region 规整,为后续对象分配提供连续空间;
- 无需并发执行,纯 STW 即可保证效率,因为新生代对象 "朝生夕死",存活比例极低,复制开销极小。
流程 2:Mixed GC(混合回收)------ 核心流程、可预测停顿、部分并发 + 部分 STW
Mixed GC 是 G1 的设计精髓 ,也是替代传统 CMS 老年代回收 + Full GC 的核心流程,同时回收新生代所有 Region + 部分老年代 Region ,是 G1 唯一会执行并发标记的 GC 流程。
Mixed GC 的核心是 **「并发标记(不 STW)+ 筛选回收(可控 STW)」**,既保证了低延迟,又能回收老年代的垃圾,是 G1 实现 "大内存 + 可预测停顿" 的关键。
1. 触发条件
老年代 Region 的整体使用率达到阈值 (默认 45%,-XX:InitiatingHeapOccupancyPercent配置),即堆的整体内存使用率达标(G1 以整堆使用率判断,而非单独老年代)。
注意:Mixed GC不会主动触发 ,而是由 JVM 根据堆内存使用情况自动判断,触发频率远低于 Young GC(几分钟 / 几小时一次)。
2. 完整执行步骤(4 个阶段:2 个 STW+2 个并发,停顿可控)
Mixed GC 分为初始标记、并发标记、最终标记、筛选回收 4 个阶段,其中2 个阶段纯并发(不 STW) ,2 个阶段短 STW ,且 STW 时间严格控制在MaxGCPauseMillis范围内。
阶段 1:初始标记(Initial Mark)------ STW,极短(复用 Young GC 的 STW)
- 核心作用 :标记整堆的 GC Roots 直接关联对象(包括新生代 + 老年代),同时标记老年代指向新生代的跨代引用;
- 触发优化 :此阶段无需单独触发 STW ,而是复用一次 Young GC 的 STW 时间完成(G1 的重要优化,减少额外停顿);
- 执行结果:得到整堆存活对象的 "根集",为后续并发标记做基础,STW 时间<10ms。
阶段 2:并发标记(Concurrent Mark)------ 纯并发,不 STW,耗时最长
- 核心作用 :从初始标记的根集对象出发,全量遍历整堆所有 Region 的引用链 ,标记所有存活对象,同时统计每个 Region 的垃圾比例;
- 执行逻辑 :恢复用户线程,GC 线程与业务线程并行执行 ,完成两个核心工作:
- 遍历所有 Region(Eden/Survivor/Old/Humongous),为所有存活对象打上标记;
- 统计每个 Region 的存活对象占比 ,计算垃圾比例,并按垃圾比例从高到低排序,生成回收候选列表;
- 关键特点 :
- 此阶段是 Mixed GC 耗时最长的阶段,但无任何 STW,对业务无影响;
- 会产生浮动垃圾(并发阶段用户线程新创建的对象,未被标记,需等到下一次 GC 回收),但 G1 对浮动垃圾无额外处理,不影响回收流程;
- 通过SATB 机制处理并发阶段的引用变动,保证标记的准确性。
阶段 3:最终标记(Final Mark)------ STW,短时间
- 核心作用 :修正并发标记阶段的标记偏差 ,处理并发阶段因用户线程操作导致的引用变动记录;
- 执行逻辑 :暂停所有用户线程,多线程并行处理SATB 队列 (存储并发阶段所有引用修改、对象新建的记录),补充标记未被遍历的存活对象,同时最终确认老年代 Region 的回收候选列表;
- 关键特点 :仅处理变动记录,不做全量遍历,STW 时间毫秒级(通常<50ms)。
阶段 4:筛选回收(Live Data Counting and Evacuation)------ STW,核心优化,停顿可预测
这是 G1 实现 **「停顿时间可预测」的核心阶段,也是 Mixed GC 的最后一步,核心是"按需选择 Region,可控 STW 回收"**。
- 核心作用:根据最大停顿时间,筛选待回收的 Region,采用复制算法完成新生代 + 部分老年代的回收;
- 执行逻辑 (全程 STW,多线程并行):
- 筛选 Region :结合
-XX:MaxGCPauseMillis设置的最大停顿时间,从回收候选列表 中选择垃圾比例最高的老年代 Region ,同时加入所有新生代 Region,计算总回收耗时,保证不超过阈值; - 复制存活对象 :将所有待回收 Region(新生代 + 筛选后的老年代)中的存活对象,复制到空闲的 Free Region,按对象年龄标记为新的 Survivor/Old Region;
- 重置 Region 状态:清空所有待回收 Region,将其标记为 Free Region,用于后续对象分配;
- 筛选 Region :结合
- 关键特点 :
- 仅回收筛选后的部分老年代 Region,而非全量老年代,严格控制 STW 时间;
- 全程采用复制算法,无内存碎片,回收后堆内存规整;
- 一次 Mixed GC 后,若老年代使用率仍高,JVM 会连续触发多次 Mixed GC,逐步回收老年代垃圾,直到使用率降至阈值以下。
3. 关键特点
- Mixed GC 是 G1唯一会回收老年代的 GC 流程,替代了传统的 Major GC/Full GC;
- 整体流程 **"2 个短 STW+2 个纯并发"**,STW 总时间严格控制在用户指定的阈值内;
- 回收效率高,优先回收垃圾比例高的 Region,在有限时间内释放最多内存。
流程 3:Full GC(兜底回收)------ 极少触发、长时间 STW、需彻底避免
G1 的 Full GC 是异常兜底场景 ,仅在 Mixed GC 无法释放足够内存时触发,生产环境中若频繁触发 Full GC,说明堆配置或 G1 调参存在严重问题。
1. 触发条件
- Mixed GC 筛选回收后,空闲 Region 仍不足,无法分配新对象 / 晋升对象;
- 超大对象无法找到连续的 Humongous Region;
- 显式调用
System.gc()(可通过-XX:+DisableExplicitGC禁用); - G1 并发标记阶段出现异常,导致标记失败。
2. 执行逻辑
G1 的 Full GC 采用单线程标记 - 整理算法,全程 STW,执行效率极低,步骤如下:
- 暂停所有用户线程,全量遍历整堆,标记所有存活对象;
- 单线程将所有存活对象向内存一端移动整理,使空闲内存连续;
- 清空无用对象的内存,恢复用户线程。
3. 关键特点
- STW 时间秒级甚至十几秒,对业务影响极大,是生产环境的 "性能杀手";
- G1 会尽最大努力避免触发 Full GC,正常配置下,生产环境中几乎不会出现。
三、G1 的核心工作联动逻辑
G1 的三类 GC 流程并非孤立执行,而是根据堆内存使用情况动态联动,形成完整的整堆 GC 生命周期,典型执行流程如下:
- 程序启动→新对象分配到Eden Region →Eden Region 满→触发 Young GC(STW,复制回收新生代,清空 Eden);
- 多次 Young GC 后→存活对象在 Survivor Region 间复制,年龄达阈值后晋升到 Old Region→老年代 Region 使用率逐步升高;
- 老年代 Region 使用率达阈值(默认 45%)→触发 Mixed GC(初始标记→并发标记→最终标记→筛选回收),同时回收新生代 + 部分老年代;
- 若一次 Mixed GC 后老年代使用率仍高→连续触发多次 Mixed GC,逐步回收老年代垃圾,直到使用率降至阈值以下;
- 程序继续运行,重复步骤 1-4,形成循环;
- 异常场景下(如堆内存不足、大对象分配失败)→触发 Full GC(兜底,长时间 STW)。
四、G1 的核心优化机制(对比 CMS,全维度升级)
G1 的工作原理中融入了多项核心优化,彻底解决了 CMS 的所有缺陷,也是其成为 JDK9 + 默认收集器的关键,核心优化点如下:
| 优化点 | G1 实现方式 | CMS 缺陷 |
|---|---|---|
| 无内存碎片 | 全程采用复制算法,存活对象集中存储在连续 Region | 标记 - 清除算法,产生大量内存碎片,导致大对象分配失败 |
| 停顿时间可预测 | 筛选回收阶段按需选择 Region,严格控制 STW 时间 | 无整体停顿时间控制,STW 时间随堆内存增大而增加 |
| 无并发模式失败 | Region 化管理,按需回收老年代,避免老年代内存被快速占满 | 并发阶段老年代内存不足,触发 Concurrent Mode Failure,切换为 Serial Old Full GC |
| 整堆统一管理 | 自身实现新生代 + 老年代回收,无需搭配其他收集器 | 仅负责老年代,需搭配 ParNew 做新生代回收,逻辑复杂 |
| 跨代引用优化 | SATB 机制 + 卡表,仅处理引用变动记录,避免全堆扫描 | 重新标记阶段全量扫描,开销随堆内存增大而增加 |
| 超大对象优化 | 单独的 Humongous Region 存储,连续分配,避免碎片化影响 | 无专门大对象区,大对象易因碎片无法分配 |
五、G1 核心配置参数
G1 的工作行为可通过 JVM 参数精准控制,核心参数均为 JDK8 + 可用,生产环境中优先使用默认值,仅在出现性能问题时针对性调参:
# 核心开启参数
-XX:+UseG1GC # 开启G1收集器(JDK9+默认,JDK8需手动开启)
# 停顿时间控制(核心调参项)
-XX:MaxGCPauseMillis=200 # 设置GC最大停顿时间,默认200ms,根据业务需求调整(如低延迟场景设为100ms)
# Region大小配置
-XX:G1HeapRegionSize=4M # 指定Region大小(1M~32M,2的幂次),默认自适应,大内存场景可适当调大
# 老年代回收触发阈值
-XX:InitiatingHeapOccupancyPercent=45 # 老年代使用率达45%时触发Mixed GC,默认45%,堆内存不足时可适当调低
# 新生代占比控制
-XX:G1NewSizePercent=5 # 新生代Region最小占比,默认5%
-XX:G1MaxNewSizePercent=60 # 新生代Region最大占比,默认60%
# 禁用显式Full GC
-XX:+DisableExplicitGC # 禁止通过System.gc()显式触发Full GC,默认关闭
# GC线程数配置
-XX:ParallelGCThreads=8 # STW阶段的并行GC线程数,默认等于CPU核心数
-XX:ConcGCThreads=4 # 并发阶段的GC线程数,默认是ParallelGCThreads的1/4
六、核心总结
G1 通过Region 化整堆管理 将堆划分为大小相等的内存块,基于垃圾优先策略 按垃圾比例排序 Region,通过三类分层 GC 流程 实现全堆回收:Young GC 高频短停顿回收新生代 ,Mixed GC(核心)通过 "并发标记 + 可控筛选回收" 同时回收新生代 + 部分老年代,保证停顿时间可预测 ,Full GC 仅作为异常兜底 ;全程采用复制算法 实现无内存碎片回收,结合SATB 机制 优化跨代引用,彻底解决了经典 GC 的缺陷,是 JDK8 + 生产环境大内存、低延迟场景的首选收集器。
核心记忆点
- G1 的核心是 **「Region 化 + 垃圾优先 + 可预测停顿」**;
- Mixed GC 是 G1 唯一回收老年代的流程,也是实现低延迟的关键;
- G1 全程复制算法,无内存碎片,是对比 CMS 最核心的优势;
- G1 的 STW 时间由
-XX:MaxGCPauseMillis精准控制,适配绝大多数低延迟业务场景。