请比较 Java 中 CMS 垃圾回收器与 G1 垃圾回收器在记忆集(Remembered Set)维护机制上的不同点。
考察说明
考察候选人对 JVM 垃圾回收器内部机制,特别是不同收集器记忆集设计差异的理解深度。
回答思路
- 【回答框架 1】记忆集用于记录非收集区域对象对收集区域的引用,以便在回收时快速定位根。CMS 的记忆集主要维护在老年代对年轻代的引用,由于 CMS 采用标记-清除算法,其记忆集在并发标记阶段需要处理并发修改,通常使用卡表(Card Table)实现,并通过写屏障维护。
- 【回答框架 2】G1 的记忆集更为复杂,它将堆划分为多个 Region,每个 Region 都维护一个记忆集,记录其他 Region 对其的引用。G1 的记忆集采用卡表(Card Table)加位图(Bitmap),并可能使用其他数据结构如 PRT(Per-Region Table)来优化空间和效率。
- 【回答框架 3】在维护方式上,CMS 的写屏障相对简单,而 G1 的写屏障更复杂,因为需要处理跨 Region 的引用。G1 的记忆集维护成本更高,但能支持更精细的回收粒度,如混合回收。
- 【回答框架 4】内存占用方面,CMS 的记忆集只针对老年代到年轻代的引用,相对较小;G1 的记忆集因为每个 Region 都有,且要记录跨 Region 引用,内存占用更大,但通过压缩和过滤机制控制。
- 【关键点 1】CMS 记忆集主要记录老年代对年轻代的引用,使用卡表实现。
- 【关键点 2】G1 记忆集为每个 Region 维护,记录所有跨 Region 引用,结构更复杂。
- 【关键点 3】两者都使用写屏障维护,但 G1 的写屏障处理更频繁且复杂。
- 【关键点 4】G1 记忆集内存开销更大,但支持更灵活的回收策略。
- 【易错点 1】误认为 CMS 记忆集记录所有代际引用,实际只记录老年代到年轻代的引用。
- 【易错点 2】以为 G1 记忆集只使用卡表,忽略位图和 PRT 等辅助结构。
- 【易错点 3】将记忆集与卡表等同,记忆集是抽象概念,卡表是实现方式之一。