G1混合回收日志中CSet动态裁剪由三要素决定:入选Region、优先级依据(垃圾占比/预测耗时/RSet大小)、数量校正逻辑(基于目标停顿时间误差反馈及IHOP阈值)。

要看懂G1混合回收日志中收集集合(CSet)的动态裁剪与分配过程,核心是抓住三个关键动作:谁被选进来了、为什么是它、数量怎么定下来的。这不是静态列表,而是G1在Evacuation Pause准备阶段实时计算的结果,全程不STW,但逻辑严密。
看日志里这三行关键字段
打开带-Xlog:gc+ergo=debug或至少-Xlog:gc+age+region=debug的日志,重点盯:
- [Mixed GC: choosing regions] —— 这行标志着CSet裁剪正式开始,后面会列出候选Region按价值排序的前若干个
- [GC pause (G1 Evacuation Pause) (mixed), 5 regions] —— 括号里的数字就是本轮实际选入的老年代Region数(不含Eden/Survivor)
- [CSet: 5 old, 12 eden, 2 survivor] —— 明确拆解CSet构成,老年代Region数量一目了然
识别“高价值Region”的真实信号
价值排序不是凭空来的,日志里会暴露依据。关注每条[Choosing region ...]行末尾的指标:
- garbage: 82% —— 垃圾占比越高,越优先;低于G1MixedGCLiveThresholdPercent(默认85%)的直接跳过
- predicted time: 1.2ms —— G1基于历史数据预测该Region回收耗时,越低越“划算”
- RSet: 4096 bytes —— Remembered Set越小,跨区扫描开销越低,优先级越高;若显示RSet too large,基本会被延后
理解数量浮动背后的校正逻辑
同一个应用,某天混合回收选3个Region,下一次变成7个,不是随机,而是G1在做误差反馈:
- 如果上一轮actual time: 210ms > target: 200ms,本轮就会主动减Region(比如-1或-2),日志里可能伴随reducing CSet due to prediction overshoot
- 如果连续两次actual: 130ms远低于目标,G1会试探性加Region,日志出现increasing CSet size for throughput
- 若老年代占用率突然冲到65%(远超IHOP默认45%),即使超时也会强行多选,日志提示over IHOP threshold, expanding CSet aggressively
排查异常裁剪的典型线索
当CSet长期偏小(如稳定1–2个),但Old Gen使用率持续爬升,别急着调参数,先查日志里有没有这些信号:
- 大量Region标着live: 92% (exceeds threshold) → 活跃对象估算偏高,检查是否误判中等生命周期对象为长期存活
- 频繁出现Humongous region skipped → 大对象堆积导致可选Region池萎缩
- to-space exhausted紧接在mixed gc之后 → CSet太小+晋升太快,空间没及时腾出,需降低MaxGCPauseMillis或提高G1HeapWastePercent










