G1回收效率以停顿时间目标为核心,动态权衡收益(可回收空间)与成本(复制存活对象耗时),按收益/成本比优先回收高价值Region,并受-XX:MaxGCPauseMillis约束动态裁剪回收范围。

G1 回收效率不靠单次吞吐量衡量,而是围绕“停顿时间目标”动态权衡回收收益与执行成本。它不追求一次清空最多垃圾,而是优先清理“单位时间释放空间最多”的区域(Region),让每次 STW 都尽可能值回票价。
回收效率的核心计算逻辑
G1 的效率本质是“收益/成本”比值决策,不是简单统计回收了多少字节:
- 收益 = 当前 Region 中可回收的垃圾空间大小(即存活率低 → 垃圾多 → 收益高)
- 成本 = 复制存活对象所需时间(取决于存活对象数量、大小、跨 Region 引用复杂度)
- 优先级排序:G1 在 Cleanup 阶段为每个 Old Region 计算“回收价值”,按收益/成本降序排列,选出最值得回收的一批 Region 进入 Mixed GC
- 动态裁剪:受 -XX:MaxGCPauseMillis 约束,G1 会预估本次回收耗时;若预估超时,就少选几个 Region,宁可多跑几次 Mixed GC,也不突破停顿目标
关键监控指标与实操建议
效率好不好,不能只看 GC 次数或回收量,得盯住三个联动指标:
- 混合 GC 频率:健康值应
- 并发标记耗时:应稳定在 5 秒内。耗时增长往往预示堆增长过快、对象存活期变长,或 RSet 维护开销上升(比如大量跨 Region 引用)
- 疏散失败(Evacuation Failure)次数:必须为 0。一旦发生,说明空闲 Region 不足,G1 被迫退化为 Full GC —— 这是效率崩盘的明确信号,常见于 Humongous 对象突增或堆碎片严重
辅助诊断的实用手段
光看数字不够,得结合日志和参数定位根因:
- 开启详细 GC 日志:-Xlog:gc*,gc+heap=debug,gc+ergo*=trace(JDK10+),重点关注 “Mixed GC” 和 “Concurrent Cycle” 的起止时间、处理 Region 数、平均复制时间
- 检查 Region 分布:jstat -gc <pid> 中的 G1YGC(Young GC 次数)、G1FGC(Full GC 次数)和 G1MixedGCTime(Mixed GC 总耗时)
- 验证 RSet 健康度:若 Concurrent Marking 阶段耗时飙升,配合 -XX:+PrintGCDetails 查看 “Remembered Set” 扫描是否成为瓶颈(日志中出现 “RS scanned” 高占比)
- 排查 Humongous 压力:用 -XX:+PrintGCDetails 观察 “Humongous Allocation” 日志频次;若频繁出现,考虑调大 -XX:G1HeapRegionSize(如从默认 2MB 调至 4MB),减少巨型对象拆分和 RSet 开销

















