判断G1中Mixed GC是否高效,关键看其能否在合理时间内清理应处理的老年代Region且不拖慢应用,需重点分析日志中的触发条件、停顿构成和回收效果三类信息。

直接看混合回收(Mixed GC)在 G1 中是否高效,关键不是“有没有执行”,而是它是否在合理时间内清掉了该清的老年代 Region,同时没拖慢整体应用。重点盯日志里的三类信息:触发条件、停顿构成、回收效果。
看 Mixed GC 是怎么被触发的
混合回收不是定时来,而是由 G1 的老化策略驱动。日志里出现 G1 Evacuation Pause (mixed) 时,要确认它是不是在“老年代使用率达标”后启动的:
- 检查前一次 GC 日志末尾是否有类似 old: 4256.0MB (42.6%) -> 4256.0MB (42.6%) 的行,再结合 G1OldCSetRegionThresholdPercent(默认 80%)判断——如果老年代已用超 60%~70%,但长期不 Mixed,说明晋升过快或阈值设得太高
- 若频繁看到 Humongous Allocation 或 HU > 5%(用 jstat -gc 查),说明大对象直入老年代,绕过年轻代筛选,导致 Mixed GC 被迫处理大量本不该进老年代的对象
拆解单次 Mixed GC 的耗时分布
G1 日志里每轮 Mixed GC 都会分阶段打印时间,真正影响响应的不是总耗时,而是其中不可并发的部分:
- Ext Root Scanning:扫描线程栈、静态变量等根节点,应稳定在 1–3ms;若突增到 10ms+,说明业务线程创建了过多强引用链(如嵌套 Map、递归缓存)
- Update RS / Scan RS:Remembered Set 更新与扫描。若 [RS scan: 25.3ms] 占总 pause 超 40%,就是瓶颈——说明跨 Region 引用太密,需调大 -XX:G1HeapRegionSize 或收拢缓存写入范围
- Evacuation:对象复制本身。若此项占比高(如 >60%)且 Eden/Survivor 区回收量小,说明选中的 CSet 里存活对象太多,Region 活跃度虚高,可调低 -XX:G1MixedGCCountTarget 让它少混一点、多跑几次
验证回收是否真正有效
不能只看“回收了多少 MB”,而要看它是否缓解了老年代压力并抑制 Full GC:
立即学习“Java免费学习笔记(深入)”;
- 对比连续几次 Mixed GC 前后的 old gen used 变化:理想情况是每次下降 5%~15%;若多次后仍持平甚至上涨,说明晋升速率>回收速率,需查对象是否过早晋升(比如 Survivor 区太小、-XX:MaxTenuringThreshold 过低)
- 观察日志中是否穿插 to-space exhausted 或 concurrent mode failure:这是 Mixed GC 失败信号,意味着它来不及回收,G1 被迫退化为 Full GC,必须干预
- 统计单位时间内 Mixed GC 次数与对应的老年代释放量比值:例如 1 小时内发生 12 次 Mixed GC,共释放老年代 1.2GB,平均每次 100MB —— 若这个值持续低于 50MB,说明 CSet 选得不准或 Region 太碎


















