G1的“Garbage First”指优先回收单位时间收益最高的Region:收益=(Region大小−存活对象大小)÷(复制耗时+RSet扫描开销),受垃圾占比、存活对象特征及RSet引用复杂度共同影响,而非单纯按垃圾量排序。

G1的“Garbage First”不是字面意义的“先收垃圾”,而是指它会动态评估每个Region的回收价值,优先选择那些“单位时间能清理最多垃圾”的区域来回收。这个决策过程依赖于并发标记阶段产出的收益模型,而非简单统计存活对象少就选它。
Region回收价值怎么算?
G1并不只看“哪个Region垃圾多”,而是综合考量三个维度:可回收空间、回收成本(复制开销)、跨Region引用复杂度。最终得出一个“收益比”:
- 可回收空间 = Region当前已用空间 − 存活对象占用空间
- 回收成本 ≈ 存活对象数量 × 复制耗时 + RSet扫描开销
- 收益 = 可回收空间 ÷ 回收成本
比如一个Old Region有80%垃圾,但里面全是大对象且跨Region引用密集(RSet条目多),它的实际收益可能低于一个只有60%垃圾但全是小对象、RSet干净的Region。
记忆集(Remembered Set)如何影响选择?
每个Region都维护自己的Remembered Set(RSet),记录哪些其他Region有指向它的引用。RSet越大,说明该Region被外部引用越频繁,Mixed GC时需额外扫描和校验,拖慢回收速度。G1在排序时会把RSet大小作为成本项加权,因此:
- RSet大的Region,即使垃圾多,也可能排在后面
- RSet小的Region,哪怕垃圾比例中等,也容易入选本轮Mixed GC
- Humongous Region默认不参与Mixed GC,除非显式配置开启
混合回收(Mixed GC)怎么挑Region?
Mixed GC不是一次性清空所有Old Region,而是在每次停顿窗口内,按收益从高到低“抓一批”:
- 先剔除RSet过大或存活率过高的Region(比如存活率>95%,复制得不偿失)
- 再按收益排序,取前N个Region,确保总预期停顿时间不超过用户设定的-XX:MaxGCPauseMillis
- 如果某次Mixed GC后,仍有大量低收益Old Region堆积,G1会触发更多轮Mixed GC,直到满足暂停目标或老年代使用率回落到阈值以下
为什么有时“垃圾最多”的Region没被选中?
常见原因包括:
- 该Region刚被Young GC扫描过,尚未进入并发标记的候选池
- 它属于Humongous Region,且未配置-XX:+G1UseAdaptiveIHOP或-XX:G1HeapRegionSize过大导致无法拆分
- 其RSet正在被并发更新(如应用线程正写入引用),G1为避免一致性问题暂不纳入本次回收
- 虽然垃圾占比高,但存活对象都是长生命周期大对象,复制成本远超收益
本质上,“Garbage First”是带约束优化的问题求解——在停顿时间硬限制下,最大化单位时间内存释放量。

















