记忆集与卡表

为了解决对象跨代引用所带来的根节点枚举问题,垃圾收集器在新生代中建立了名为

记忆集(Remembered Set)的数据结构,用以避免把整个老年代加入GC Roots扫面范围。

记忆集的实现方案

记忆集是一种抽象的数据结构,用于记录从【非收集区域】指向【收集区域】的指针集合的抽象数据结构。

可以有多种实现,如:

  • 字长精度

    每个记录精确到一个机器字长,该字包含跨代指针。

  • 对象精度

    每个记录精确到对象,该对象里有字段含跨代指针。

  • 卡精度

    每个记录精确到一块内存区域,该内存区域有对象含有跨代指针。

卡表(Card Table)

卡精度就是用一种称为卡表(Card Table)的方式去实现记忆集,这是目前最常见的一种记忆集实现方式。

卡表最简单的形式只是一个字节数组,HotSpot虚拟机默认的卡表标记逻辑:

CARD_TABLE [this address >> 9] = 0;

字节数组CARD_TABLE的每一个元素都对应着标识的内存区域中一块特定大小的内存空间,

这个内存空间被称为“卡页”(Card Page)。一般卡页大小都是2的N次幂的字节数。

HotSpot中使用的是卡页是2的9次幂,即512字节(地址右移9位,上边的卡表标记代码也可看出)。

一个卡页的内存中通常包含不止一个对象,只要卡页内有一个对象存在跨代指针,

那么对应的卡表的数组元素的值标识为1,称这个元素变脏(Dirty),没有则标识为0。

垃圾回收时,只需要筛选出卡表中变脏的元素,就能得到哪些卡页内存块中包含跨代指针,从而将

它们加入GC Roots中一并扫描。