G1垃圾回收器采用分区、增量、价值驱动的回收策略。它将堆划分为大小相等的Region,动态分配角色,支持并发标记(SATB+TAMS)与Mixed GC,并基于预测模型实现可控停顿。

G1 垃圾回收器不是“一次扫完整个堆”,而是用一套动态、分区、可预测的策略来管理内存。它把停顿时间控制放在首位,不追求绝对最短,而是让每次 GC 停顿尽量稳定、可控——比如你设了 -XX:MaxGCPauseMillis=200,G1 就会努力让每次 STW 接近但不超过 200ms。
Region 分区:打破物理分代的老框框
G1 把整个堆切成多个大小相等的 Region(通常 1–32MB),每个 Region 可动态扮演 Eden、Survivor 或 Old 角色。没有固定边界,也不强制连续——老年代和新生代只是逻辑概念,Region 之间可以自由切换身份。这种设计带来两个关键好处:
- 避免大块内存碎片:回收时按 Region 整体腾挪,天然支持压缩;
- 支持增量式回收:每次只选一部分 Region 回收,不用锁死全部堆。
回收价值驱动:优先清理“最脏”的区域
“Garbage First” 的名字就来自这个逻辑:G1 会持续跟踪每个 Region 的垃圾占比和回收成本(扫描+复制耗时),形成一张“回收价值排行榜”。每次 Young GC 或 Mixed GC 时,它不是随机挑 Region,而是从最“高收益低开销”的几个 Region 入手——也就是垃圾最多、存活对象最少、搬运最快的那一组。
这就像清洁工进仓库,不挨个扫,而是先冲向堆满废纸箱的角落。
并发标记 + SATB + TAMS:边运行边标记的底层保障
标记阶段不是 STW 完成的,而靠三者协同:
- SATB 写屏障:在标记开始瞬间拍一个“快照”,之后所有被修改引用的对象(比如断开旧引用)都会被记录到缓冲队列;
- TAMS 指针:标记启动时冻结堆顶位置,TAMS 上方新分配的对象默认视为存活(隐式标记),不参与本次扫描;
- 最终标记阶段:一次短暂停顿,专门处理 SATB 队列里的“漏标风险对象”,确保不会误删还活着的引用。
这套机制让大部分标记工作能和应用线程并发进行,大幅压缩 STW 时间。
Mixed GC 与可预测停顿模型
G1 不区分“只清年轻代”或“只清老年代”,它用 Mixed GC 同时回收部分年轻代 Region 和部分老年代 Region。触发条件不是老年代满了,而是:
- 并发标记周期完成;
- 老年代占用率超过阈值(
-XX:InitiatingHeapOccupancyPercent,默认 45%); - 且有足够多的待回收老 Region 被标记为候选。
更重要的是,G1 内置一个运行时预测模型:根据历史 GC 数据(各 Region 处理耗时、对象晋升速率、扫描速度等),动态估算本次回收哪些 Region 能在目标停顿时间内完成。它不是硬性截断,而是主动取舍——宁可少收几个 Region,也不能超时。

















