Region划分是G1可预测停顿的物理基础,其大小与数量直接影响回收粒度、Remembered Set开销及Humongous Region行为,需根据堆大小和对象特征合理配置以平衡停顿时间与元数据成本。

Region 划分是 G1 控制 STW 停顿时间的底层前提,不是“辅助手段”,而是整个可预测停顿模型的物理基础。
Region 大小和数量直接决定单次回收的粒度上限
每个 Region 是 GC 工作的最小单位,G1 从不扫描整代内存,只挑若干 Region 回收。这意味着:
-
G1HeapRegionSize设置过大会导致单个 Region 回收耗时不可控(比如设成 32MB,一个满的 Eden Region 可能含数万对象,复制+标记时间飙升); - 设得太小(如 1MB)则 Region 数量暴涨(64GB 堆可达 65536 个),Remembered Set 维护开销剧增,反而拖慢并发标记阶段;
- 默认自动计算的 Region 大小在多数场景下合理,但若堆 >32GB 且业务对象普遍中等大小(如 200KB~1MB),建议显式设为
4m或8m,平衡粒度与元数据成本; - Region 数量上限默认 2048,超过该数会强制缩小 Region 大小 —— 这不是弹性扩容,而是降级妥协,容易引发隐性碎片和 Mixed GC 效率下降。
Humongous Region 是 STW 时间突增的常见隐藏源头
大对象(≥50% Region Size)被直接分配进 Humongous Region,而这类 Region:
- 不参与 Young GC,仅在 Mixed GC 的 Cleanup 阶段或 Full GC 时才可能被回收;
- 若对象跨多个连续 Region(
StartsHumongous+ContinuesHumongous),回收时需一次性锁定全部关联 Region,STW 时间与占用 Region 数线性相关; - 频繁分配
byte[8MB]类缓冲区(Region Size=16MB 时即触发 Humongous),会导致大量零散的 H-Region 占用老年代空间,挤压 Mixed GC 可选 Region 池; - 监控时注意
G1HumongousAllocation日志项,它比GC pause (G1 Evacuation Pause)更早暴露问题 —— 分配失败本身就会触发一次紧急 Young GC。
停顿时间目标(MaxGCPauseMillis)生效的前提是 Region 价值评估有足够样本
G1 靠历史回收数据拟合每个 Region 的「收益/耗时比」,这个模型需要冷启动:
- 新启动应用前 20 次 GC 属于预热期,
MaxGCPauseMillis=50可能实际停顿仍达 150ms,因衰减平均值davg和标准偏差dsd尚未收敛; - Region 回收价值依赖两个真实观测值:实际释放空间(KB)、STW 耗时(ms),若某类 Region 总是「垃圾少但耗时长」(如含大量 finalizer 的对象),G1 会逐步降低其优先级 —— 但这需要至少 5 次回收样本(
confidence_factor触发条件); - 当堆内 70% 以上 Region 长期处于低垃圾占比(
Region 不是抽象概念,它是内存里真实存在的、可被单独锁定和搬运的块。控制 STW 的本质,就是让 JVM 始终有「小而确定」的单元可操作。一旦 Region 粒度失控(过大、过多、被大对象霸占),所有基于它的预测模型都会失准 —— 此时调 MaxGCPauseMillis 只是在调期望,不是在调结果。










