古代 JVM,堆空间通常被划分为新生代和老年代。因为新生代的垃圾收集通常很频繁,如果老年代对象援用了新生代的对象,那么,须要跟踪从老年代到新生代的所有援用,从而防止每次 YGC 时扫描整个老年代,缩小开销。
对于 HotSpot JVM,应用了卡标记(Card Marking)技术来解决老年代到新生代的援用问题。具体是,应用卡表(Card Table)和写屏障(Write Barrier)来进行标记并放慢对 GC Roots 的扫描。
卡表(Card Table)
Card Table 通常将堆空间划分为一系列 2 次幂大小的卡页(Card Page)。
Card Table,用于标记卡页的状态,每个卡表项对应一个卡页。
HotSpot JVM 的卡页(Card Page)大小为 512 字节,卡表(Card Table)被实现为一个简略的字节数组,即卡表的每个标记项为 1 个字节。
当对一个对象援用进行写操作时(对象援用扭转),写屏障逻辑将会标记对象所在的卡页为 dirty。
当产生 yanggc 的时候,老年代只须要扫描卡表中的脏页。
卡表也用于 cms 回收二阶段。并发标记阶段会把发生变化的对象所在的 Card 标识为 Dirty,这样后续阶段就只须要扫描这些 Dirty Card 的对象,从而防止扫描整个老年代。
-XX:+UseCondCardMark:在执行写屏障之前,先简略的做一下判断。如果卡页已被标识过,则不再进行标识。
https://www.cnblogs.com/hongd…