Remembered Set(记忆集)与卡表(Card Table)的关系解析

dalang · · 60 次点击 · · 开始浏览    
--- ### **1. 核心概念** • **Remembered Set(记忆集)**: 一个**抽象概念**,指垃圾收集器(GC)中用于**记录跨区域(或跨代)引用**的数据结构。例如,在分代GC中,记忆集记录老年代对象对年轻代的引用,避免全堆扫描。 • **Card Table(卡表)**: 记忆集的**一种具体实现方式**,通常通过**位图(bitmap)** 标记内存块(卡页)是否包含跨区域引用。卡表是记忆集在技术实现上的具体表现。 --- ### **2. 两者的关系** • **记忆集是接口,卡表是实现**: • **记忆集**定义功能:记录外部区域到本区域的引用。 • **卡表**是其中一种实现方式,其他实现可能包括哈希表、指针数组等。 • **所有卡表都是记忆集,但记忆集不一定是卡表**: 例如,ZGC可能使用其他数据结构(如指针数组)实现记忆集,而G1默认使用卡表。 --- ### **3. 卡表的工作原理** 1. **内存分块**: 堆内存被划分为固定大小的**卡页(Card Page)**,如512字节或1KB。 ```plaintext | Card 0 | Card 1 | Card 2 | ... | Card N | ``` 2. **标记引用变更**: • 当应用线程修改对象引用时(如老年代对象A引用年轻代对象B),**写屏障(Write Barrier)** 会标记对应的卡页为“脏”(Dirty)。 • 例如,对象A所在的卡页被标记为脏页。 3. **GC阶段扫描**: • 在年轻代GC时,只需扫描**脏卡页**中的对象,快速找到跨代引用,避免扫描整个老年代。 --- ### **4. 卡表的优缺点** • **优点**: • **空间效率高**:用位图标记卡页,占用内存小。 • **更新快速**:写屏障仅需设置位图位,开销低。 • **缺点**: • **精度不足**:一个卡页被标记为脏,需扫描整个卡页内所有对象(即使只有1个引用)。 • **维护开销**:频繁修改引用时,写屏障可能影响吞吐量。 --- ### **5. 示例场景** • **分代GC(如ParNew+CMS)**: • 老年代对象A引用年轻代对象B。 • 卡表标记A所在的卡页为脏。 • 年轻代GC时,仅扫描脏卡页,发现A→B的引用,将B晋升到老年代。 • **G1的Region化堆**: • 每个Region对应一个记忆集(卡表实现)。 • Region Y的记忆集记录所有指向Y的外部引用所在的卡页。 --- ### **6. 其他记忆集实现** • **指针数组**: 直接存储跨区域引用的指针列表(如ZGC的部分实现)。 • **优点**:精确到单个引用。 • **缺点**:空间占用大,更新成本高。 • **哈希表**: 按对象地址哈希存储跨区域引用。 • 适用于稀疏引用场景,但查询复杂度较高。 --- ### **7. 总结** • **记忆集(Remembered Set)**: 广义的跨区域引用记录机制,是垃圾收集器的核心数据结构。 • **卡表(Card Table)**: 记忆集的一种高效实现方式,通过位图标记内存块,平衡精度与性能。 • **关键区别**: • 记忆集是逻辑概念,卡表是物理实现。 • 卡表牺牲部分精度换取空间和时间效率,而其他实现可能更精确但成本更高。 **实际应用**: • G1、CMS等收集器默认使用卡表实现记忆集。 • 在需要高精度时(如实时系统),可结合其他数据结构优化。
60 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传