主题
G1 的 Region、并发标记和 Remembered Set 是怎样协同工作的?
题型:深入 · 重点解释停顿阶段、并发阶段和跨 Region 引用维护。
建议回答
G1 把堆划分为大小相等的 Region,年轻代、老年代和 Humongous 区域是 Region 的动态角色,而不是固定连续分区。年轻代回收会暂停应用线程,把存活对象复制到 Survivor 或老年代;当老年代占用达到阈值后,G1 启动并发标记,估算各 Region 的存活量,再在 Mixed GC 中优先选择垃圾收益高、预计能满足停顿目标的老年代 Region,与年轻代一起回收。
并发标记采用 SATB 思路,尽量保留标记开始时的对象图快照。应用线程修改引用时,写屏障会把被覆盖的旧引用记录到队列,标记线程随后处理,避免并发修改造成漏标。Remembered Set 则记录指向某个 Region 的外部引用来源,使回收一个 Region 时无需扫描整个堆;它依赖卡表和写屏障维护,因此会消耗额外 CPU 和内存。
G1 能做的是以预测模型尽量接近最大停顿目标,不是保证每次停顿都低于目标。并发标记跟不上分配速度、疏散阶段没有足够空 Region、Humongous 对象过多或引用更新压力很大时,仍可能出现长停顿甚至退化回收。
关键权衡
- 更积极地满足停顿目标通常意味着更频繁 GC、更低吞吐或需要更大堆余量。
- 更大的 Region 会减少 Region 数量和管理开销,但可能加剧内部碎片,并改变 Humongous 对象判定。
- Remembered Set 缩小了回收扫描范围,却增加写屏障、精炼线程和元数据成本。
易错点
- 不要把 G1 说成完全无停顿;初始标记、重新标记和对象疏散等阶段仍需要 STW。
- 不要说 Mixed GC 会一次清空所有老年代,它只选择一部分收益较高的 Region。
- 不要承诺设置
MaxGCPauseMillis就一定达到该停顿时间,它只是软目标。