现代JVM,堆空间通常分为新生代和老年代。由于新生代的垃圾回收通常非常频繁,如果老年代的对象引用了新生代的对象,那么需要跟踪老年代对新生代的所有引用,避免扫描整个老年代每次生成YGC并减少开销。对于HotSpotJVM,采用卡片标记(CardMarking)技术解决老年代到新生代的引用问题。具体来说就是利用卡表(CardTable)和写屏障(WriteBarrier)来标记,加快GCRoots的扫描。卡表(CardTable)CardTable通常将堆空间划分为一系列2次方大小的卡页(CardPage)。卡片表,用于标记卡片页的状态,每个卡片表项对应一个卡片页。HotSpotJVM的CardPage大小为512字节,CardTable实现为一个简单的字节数组,即CardTable中的每个标签项为1个字节。当对对象引用执行写操作时(对象引用发生变化),写屏障逻辑会将对象所在的卡片页标记为脏。当发生anggc时,老年代只需要扫描card表中的脏页即可。卡表也用于cms恢复的第二阶段。并发标记阶段会将变化对象所在的Card标记为脏,这样后续阶段只需要扫描这些脏卡片的对象,从而避免扫描整个老年代。-XX:+UseCondCardMark:在执行writebarrier之前,做一个简单的判断。如果卡片页面已经被标记过,则不会再被标记。https://www.cnblogs.com/hongd...
