G1 Region 与 Remembered Set
候选人小庞在面试阿里 P7 时,面试官问道:
"G1 的 Remembered Set 是什么?它是怎么工作的?"
小庞说:"Remembered Set 记录 Region 之间的引用关系..."面试官追问:"Remembered Set 的内存占用大吗?"
小庞答不上来...
一、核心问题:Remembered Set 🔴
1.1 问题拆解
1.2 标准回答
P5 级别:Remembered Set 的作用
为什么需要 Remembered Set?
在 G1 中,GC 时需要知道哪些 Region 引用了当前 Region,以避免全堆扫描。
Remembered Set 记录了指向当前 Region 的引用来自哪些其他 Region。
P6 级别:实现方式
PointIn vs PointOut:
PointIn 实现(当前 Region 的 RS):
每个 Region 维护一个 Remembered Set,记录指向该 Region 的其他 Region。
P7 级别:内存开销
Remembered Set 的内存开销:
Remembered Set 的内存占用与跨 Region 引用数量成正比:
- 理论占用:堆的 10%~20%(高引用变化率场景下可能更高)
- G1 的 Remembered Set 使用稀疏表存储(每个 Region 一个小数组)
写屏障的更新代价:
每次对象引用赋值都会触发写屏障,更新相关 Region 的 Remembered Set。
【面试官心理】 这道题我能问到 P7 级别,是因为 Remembered Set 的内存开销是 G1 在大内存堆上的主要瓶颈。
1.4 追问升级
追问:ZGC 的 NMT(Native Memory Tracking)可以查看 Remembered Set 吗?
ZGC 使用 Colored Pointers 代替 Remembered Set,不需要维护 Region 间的引用关系。NMT 可以查看 ZGC 自身的内存使用,但不包含 Remembered Set。
二、生产调优 🟡
2.1 减少 Remembered Set 更新
面试加分点:能说出"JDK 14 实现了 G1 的 Region Flipping 优化,减少了 Remembered Set 的维护开销",说明他关注了 JDK 新特性。
面试陷阱:被问到"Remembered Set 在 GC 完成后会被清理吗",很多人会说"不会"。准确答案是:Remembered Set 在每次 GC 完成后会被清理,因为每次 GC 后 Region 的引用关系可能发生变化,需要重新记录。