跨代引用

在 JVM 虚拟机的内存管理中,有可能存在老年代对象引用新生代的情况,在 Major GC 时,为了标记这些引用的新生代对象,需要通过扫描老年代来间接标记。

然而,正常扫描全部老年代来获取的做法效率太低下了,由此便产生了称为 CardTable (卡表) 的数据。

Card Table 保存了所在由老年代所引用的新生代对象的集合,同时利用写屏障,在引用对象变化时,对引用记录标记为 “脏” ,那么当下次 GC 到来时,只用扫描脏页 (Dirty Page) 便可以标记出由老年代引用的新生代存活对象。并且在 GC 后,由于复制算法导致了数据的迁移,根据迁移的位置决定是否对引用记录再次进行标记。

在 G1 中,除了 Card Table 还存在 Remembered Set,更好的解决了跨代引用的问题。

它记录了新生代被老生代引用的记录,存活于 Region 中,对比 Card TableRemembered Sets 只需通过自身就能得知是否存在跨代引用,无需借助老年代。

配合 G1 回收算法,在对 Region 进行回收时,无需借助外部数据就能获取全部存活对象,更大的提高了 GC 的效率。

其实在 G1 中,Remembered Sets 是借助 Card Table 来实现的。

http://blog.ragozin.info/2011/06/understanding-gc-pauses-in-jvm-hotspots.html