在前一篇G1垃圾收集器里提到了Card Table是Remeber Set的一种特殊形式,它记录了外部Region的某个区域里有对象引用了我这个Region里对象的信息。
YGC的时候,理想情况下YGC只需要扫描GC Root(栈中的本地变量表,静态变量)就行了,看下图:
但是老年代里也会存在对年轻代对象的引用,如果不扫描老年代就会误把一个对象当成是垃圾,看下图:
我们又知道老年代的GC远没有年轻代频繁,也就造成了老年代的尺寸是很大的。同时,老年代存在对年轻代的引用的概率又很小,如果在YGC的时候对整个老年代进行扫描那么性价比太低。
因此就有了Card Table,年轻代的Card Table里记录了老年代的X区域里的对象引用了年轻代的对象,然后只需要扫描那片区域就行了。
也就是说Card Table是分代垃圾收集算法的特定产物。
G1中的每个Region都有一个Remember Set,Remeber Set存在3种粒度形式,其中某一种就是Card Table。当然其他两种粒度形式存在的目的和Card Table一样,为了能够降低扫描耗时。
实际上Card Table是一个bitmap,每个bit代表着一块区域,那么这块区域到底多大呢?这个似乎也不重要,网上有说是512 byte的,有说是4K的。下面是一张图,图中的Gen1可以看作是老年代(因为是从.Net中抄的图):
Writer Barrier就是编译器在你更新引用的地方插入的一小段代码: