2026年3月18日,JDK 26正式发布,带来了20余项JDK增强提案(JEP),其中G1 GC的三项重大升级尤为值得开发者关注——吞吐量提升5-15%、大对象回收优化、GC开销保护机制。本文由火星AI助手协助整理资料,深度解析G1 GC的核心原理与JDK 26最新特性,为技术入门与进阶学习者提供从原理到面试的一站式知识链路。
一、为什么需要G1 GC?传统GC的痛点

在JDK 9之前,Java默认的垃圾回收器是Parallel GC,它采用“Stop-The-World”(STW,全局暂停)模式,在回收期间暂停所有应用线程。当堆内存扩大到数十GB时,Full GC导致的停顿可能长达数秒甚至数十秒——对于金融交易、实时数据分析等延迟敏感型系统,这样的停顿是不可接受的。
CMS(Concurrent Mark Sweep,并发标记清除)虽然试图通过并发回收降低停顿,但它存在两个致命缺陷:内存碎片化和无法预知的Full GC。随着应用运行时间增长,CMS无法压缩堆内存,最终触发Full GC时仍会导致长停顿。

正是为了解决这些问题,G1 GC应运而生。
二、G1 GC核心概念详解
G1 GC定义
G1 GC(Garbage-First Garbage Collector,垃圾优先垃圾回收器) 是Java HotSpot虚拟机中的一款面向服务端、低延迟、高吞吐的垃圾回收器,自JDK 7u4引入,并在JDK 9成为默认垃圾回收器-61。其设计目标是在可控的停顿时间内(默认为200毫秒)实现高吞吐量,适用于大内存(数十GB甚至更大)的应用场景-61。
核心机制:Region分区
G1 GC的核心设计思想是分块(Region-Based) :将堆内存划分为多个大小相等的Region(默认约2048个,每个Region大小1MB~32MB)。每个Region可以是Eden、Survivor、Old、Humongous(大对象)或Free(空闲)中的一种-61。
生活化类比:传统GC好比整栋大楼统一打扫——不管哪个房间脏不脏,全部停下来一起扫;G1则把大楼分成2048个小房间(Region),每次只挑垃圾最多的那几个房间打扫。这样一来,每次打扫的时间可控,整栋楼的服务也不会中断太久。
关键技术点:
Remembered Set(RSet,记忆集) :每个Region维护一个RSet,记录其他Region对本Region的引用,避免全堆扫描-61
Card Table(卡表) :辅助RSet实现跨Region引用的高效追踪
Humongous Region(巨型对象区) :存放超过Region大小50%的大对象,避免多次拷贝-61
关联概念:分代回收假说
G1 GC虽然以Region为单位管理内存,但逻辑上仍保留了分代思想——即弱分代假说(Weak Generational Hypothesis):
绝大多数对象都是朝生夕死的:超过90%的对象在创建后很快就会变成不可达状态,不会熬过第一次GC
熬过越多次垃圾收集的对象,越难消亡:经过多次GC依然存活的对象,大概率会长期存活-18
基于这一假说,G1的Region动态扮演Eden、Survivor、Old的角色,让新生代对象在复制算法中快速回收,老年代对象则采用更保守的回收策略。
G1 vs 传统GC:核心差异总结
| 维度 | 传统GC(Parallel/CMS) | G1 GC |
|---|---|---|
| 堆管理方式 | 连续分代,比例固定 | Region分区,角色动态调整 |
| 停顿控制 | Full GC时间长且不可控 | 可设定MaxGCPauseMillis目标 |
| 回收策略 | 全堆回收或全老年代回收 | 优先回收垃圾比例高的Region |
| 碎片处理 | CMS不压缩导致碎片化 | G1通过复制实现压缩,避免碎片 |
一句话概括:G1 GC是分代回收思想 + Region分区实现 + 停顿可控模型三位一体的现代垃圾回收器。
三、JDK 26 G1 GC三项重大升级(2026年3月)
根据Oracle官方发布的JDK 26 Release Notes,G1 GC在JDK 26中迎来了三项关键改进-2:
1. 吞吐量提升5-15%:减少写屏障开销
JDK 26通过引入第二张卡表(second card table) ,大幅降低了G1写屏障的指令数——从50条指令减少到12条,减少幅度超过75%-2。测试数据显示,这一优化带来了5-15%的吞吐量提升,尤其是那些频繁修改对象引用字段的应用受益最为明显-2。
面试考点:写屏障(Write Barrier)是G1 GC用于追踪跨Region引用的核心机制。JDK 26通过优化写屏障指令数,在保证引用追踪准确性的同时显著降低性能开销。
2. 大对象(Humongous Object)及时回收
在JDK 26之前,占据超过半个Region大小的大对象(如大型数组、字节缓冲区等)只能在Full GC时才能被回收-2。
JDK 26的新机制:G1现在能够主动回收符合条件的含引用的大对象,特别是那些生命周期较短的大对象。这一改进使得原本长期占用内存的大对象能够被及时释放,显著降低堆内存压力-2。
3. GC开销保护机制
JDK 26为G1 GC新增了GC开销保护功能:当垃圾回收耗时超过总运行时间的98%(默认阈值),且释放的内存不足2%时,连续发生5次后JVM会抛出OutOfMemoryException-2。
面试考点:这一机制借鉴了Parallel GC的实现,可以有效防止“GC thrashing”(GC抖动)——即JVM不停做GC却无法释放有效内存的恶性循环,帮助应用快速失败而非无限卡顿。
JDK 26还修复了G1对Transparent Huge Pages(THP,透明大页) 的支持问题,使G1在配置为madvise模式的Linux系统上能够正确利用大页机制优化内存访问性能-2。
四、G1 GC代码示例与执行流程
/ G1 GC工作原理演示:模拟对象分配与垃圾回收 / public class G1GCDemo { // 模拟短生命周期对象 - 应在Young GC中快速回收 public static void createShortLivedObjects() { for (int i = 0; i < 10000; i++) { // 局部变量:方法结束后即失去引用,成为GC目标 byte[] temp = new byte[1024]; // 1KB对象 } } // 模拟长生命周期对象 - 将晋升到老年代 public static class LongLivedObject { private final long id; private final byte[] data; public LongLivedObject(long id) { this.id = id; this.data = new byte[1024 1024]; // 1MB对象 } } private static final List<LongLivedObject> cache = new ArrayList<>(); public static void main(String[] args) throws InterruptedException { // 启动参数示例(JDK 8+): // java -XX:+UseG1GC -Xms4g -Xmx4g -XX:MaxGCPauseMillis=200 -Xlog:gc G1GCDemo System.out.println("G1 GC Demo started with JDK 26"); System.out.println("Heap size: " + Runtime.getRuntime().totalMemory() / 1024 / 1024 + "MB"); // Step 1: 大量短生命周期对象 -> 触发Young GC for (int cycle = 0; cycle < 50; cycle++) { createShortLivedObjects(); Thread.sleep(100); } // Step 2: 创建长生命周期对象 -> 部分将晋升到老年代 for (int i = 0; i < 100; i++) { cache.add(new LongLivedObject(i)); } // Step 3: 模拟混合负载 for (int cycle = 0; cycle < 30; cycle++) { createShortLivedObjects(); // 新生代持续分配 Thread.sleep(200); } System.out.println("Demo completed. Cache size: " + cache.size()); } }
执行流程关键点:
Young GC(年轻代回收) :当Eden区满时触发,将Eden和Survivor中的存活对象复制到另一个Survivor区或晋升到Old区-61
Mixed GC(混合回收) :当老年代占用达到
InitiatingHeapOccupancyPercent(默认45%)时触发,并发标记后优先回收垃圾比例高的Old Region-61JDK 26优化体现:写屏障优化减少了GC过程中的同步开销;大对象回收机制确保大型数组等及时释放;GC开销保护机制防止GC thrashing
五、底层原理:G1 GC的关键技术支撑
G1 GC的高性能实现依赖于以下几个底层技术:
Remembered Set(RSet,记忆集) :每个Region维护一个RSet,记录指向本Region的外部引用,避免全堆扫描。RSet是空间换时间策略的典型应用,以约5%的内存开销换取数十倍的GC效率提升-61。
SATB(Snapshot-At-The-Beginning,起始快照)算法 :在并发标记阶段开始时记录堆中存活对象的快照,保证标记的正确性,同时允许应用线程在此期间继续修改对象引用。
Pause Prediction Model(停顿预测模型) :G1基于历史回收数据,动态估算回收指定数量Region所需的时间,确保单次GC停顿不超过用户设定的
MaxGCPauseMillis目标-56。TLAB(Thread-Local Allocation Buffer,线程本地分配缓冲区) :每个线程在Eden区拥有私有分配缓冲区,避免多线程同时分配对象时的锁竞争,提升对象分配效率-18。
底层定位:这些技术的核心思想是 “增量回收+并发执行”——将原本一次完成的大规模回收任务拆解成多个小任务,在多个GC周期中逐步完成,从而将单次停顿时间控制在可接受范围内。
六、高频面试题与参考答案
Q1:请简述G1 GC的核心设计思想及其与传统GC的区别。
参考答案:
G1 GC的核心思想是 “Garbage-First” ——优先回收垃圾比例最高的Region-56
它将堆划分为大小相等的Region(默认2048个),每个Region可动态扮演Eden、Survivor或Old的角色-61
相比传统GC,G1具备可控停顿模型(通过MaxGCPauseMillis参数设置)、增量回收(每次只回收部分Region)和自动压缩(通过复制避免碎片化)三大优势-61
Q2:JDK 26中G1 GC有哪些重要更新?
参考答案:
JDK 26(2026年3月发布)为G1 GC带来了三项关键改进-2:
吞吐量提升5-15% :通过引入第二张卡表将写屏障指令从50条减少到12条
大对象及时回收:此前仅能在Full GC时回收的大对象,现在可在Mixed GC中主动回收
GC开销保护:当GC耗时超98%且释放内存不足2%时,连续5次后抛出OOM,防止GC thrashing
Q3:G1 GC中Region是什么?RSet的作用是什么?
参考答案:
Region是G1 GC的基本内存管理单元,大小通常为1MB~32MB,堆被划分为约2048个Region-61
RSet(Remembered Set) 是每个Region维护的引用记录表,记录了其他Region中指向本Region的所有引用-61
RSet的核心价值:当回收某个Region时,G1无需扫描整个堆就能知道哪些外部对象引用了本Region内的对象,避免全堆扫描带来的长停顿
Q4:G1 GC的停顿模型是如何实现的?
参考答案:
G1通过参数
-XX:MaxGCPauseMillis(默认200ms)设定目标停顿时间-61G1内部维护一个停顿预测模型,基于历史回收数据估算回收不同数量Region所需的时间-56
每次GC时,G1在预测模型指导下选择不超过目标时间的Region数量进行回收
需要强调的是,G1并非实时GC——它以高概率满足目标停顿,但不保证绝对精确-56
七、总结
本文系统梳理了G1 GC的核心原理与JDK 26最新特性,回顾核心要点:
✅ G1 GC本质:分代回收思想 + Region分区实现 + 停顿可控模型
✅ JDK 26关键更新:吞吐量提升5-15%、大对象及时回收、GC开销保护
✅ 底层技术栈:RSet、SATB算法、TLAB、停顿预测模型
✅ 面试重点:Region概念、停顿模型实现、与Parallel/CMS的差异
易错点提示:
G1 GC虽然以Region为单位管理,但逻辑上仍保留分代思想,并非“无分代”
G1的停顿模型是“以高概率满足”,并非实时GC的硬保证
JDK 26中G1吞吐量提升主要来自写屏障优化,而非单纯的并行度增加
进阶学习方向:ZGC和Shenandoah作为新一代低延迟GC,在JDK 26中也有重要更新(如ZGC的AOT对象缓存、Shenandoah的分代模式优化),后续文章将深入探讨它们的原理与选型对比。