CMS中的卡表和G1中的卡表的区别
1. 卡表(Card Table)简介
卡表是一种写屏障(Write Barrier)技术实现,主要用于追踪堆内存中的**“脏卡”**,也就是记录哪些内存区域发生了写操作,方便 GC 时高效定位需要扫描的对象,避免全堆扫描。
卡表把堆分成固定大小的卡(Card),一般是512字节(具体大小可能不同),卡表本身是一个字节数组,每个字节代表一块卡的状态。
2. CMS中的卡表
-
主要用途:CMS采用增量式并发标记,并通过卡表记录老年代中被年轻代对象引用的部分,以便并发标记阶段快速扫描这些引用,避免扫描整个老年代。
-
卡表维护范围:主要覆盖老年代堆区域。
-
写屏障机制:CMS使用写屏障来更新卡表,当老年代某个区域被修改时,该区域对应的卡标记为“脏”,GC时只扫描这些“脏卡”对应的区域,提高效率。
-
卡表数据结构和实现:
- 一般是一个字节数组。
- 字节标记为“脏”或“干净”。
- 在CMS的并发标记过程中,卡表帮助定位需要重新扫描的老年代区域。
-
触发时机:主要在对象指针从年轻代写入老年代时触发。
3. G1中的卡表
-
主要用途:G1是分代且分区(Region-based)的GC,卡表用于追踪整个堆中所有区域之间的引用变化,支持高效的增量更新和并发标记。G1的卡表覆盖堆中所有内存区域,不仅仅是老年代。
-
卡表维护范围:覆盖整个堆(包括年轻代和老年代分区)。
-
写屏障机制:G1的写屏障实现更复杂,除了标记“脏卡”,还维护了针对不同 Region 的引用信息,方便在混合回收时快速识别跨区引用,减少扫描开销。
-
卡表数据结构和实现:
- 仍是字节数组,但结构更复杂。
- 对每张卡,不仅标记是否脏,还关联对应的 Region 信息,方便定位影响的区域。
- 支持多线程并发更新和扫描。
-
触发时机:任何堆内存写操作,更新卡表,保证 GC 能准确知道哪些区域被修改。
4. 主要区别总结
| 维度 | CMS卡表 | G1卡表 |
|---|---|---|
| 作用范围 | 主要是老年代 | 覆盖整个堆(老年代+年轻代) |
| 设计目的 | 加速老年代增量标记扫描 | 支持基于Region的细粒度增量回收 |
| 写屏障实现 | 较简单,标记对应卡是否“脏” | 更复杂,标记“脏卡”并关联Region信息 |
| 数据结构 | 字节数组,标记“脏”或“干净” | 字节数组,带Region索引信息 |
| 并发支持 | 有,但较简单 | 设计支持多线程并发访问 |
| 适用GC策略 | CMS,针对老年代并发回收 | G1,分代+分区混合回收 |
简单总结
- CMS卡表只管理老年代写操作,帮助并发标记时快速定位老年代中的跨代引用。
- G1卡表覆盖全堆,管理所有区域,支持更加细粒度的增量更新和并发回收。
- G1卡表更复杂,维护更多信息,支持更高并发和更精细的回收粒度。

浙公网安备 33010602011771号