有些文章指出OpenJDK / Oracle 1.6 / 1.7 / 1.8 JVM默认遵循卡片标记逻辑。 (http://psy-lob-saw.blogspot.hk/2014/10/the-jvm-write-barrier-card-marking.html) 但在wiki Tracing garbage collection中,它声称三色算法也有很好的表现。
我很困惑,有没有jvm使用三色标记算法?换句话说,与卡片标记算法相比,三色标记的优势在哪里?
答案 0 :(得分:1)
卡片标记不适用于单个物品;它一次用于一组对象。基本上,它是跟踪区域间参考。如果区域A,B,C中有内存,并且A中的所有对象都是自包含的,则B中的所有对象都是自包含的,并且C中的所有对象都是自包含的,那么您没有任何对象卡片标记。因此,当涉及垃圾收集A时,您不需要考虑来自B或C的任何对象来了解A中的对象是否可达 - 因此,您可以在本地清除它们。
因此,卡片标记的作用是优化执行垃圾回收时需要扫描的内存量。
如果B中的对象引用A中的对象,则会对卡表进行标记以指示存在跨区域引用。结果,当垃圾收集A时,它还需要遍历B(或者更确切地说,已经被卡标记为引用区域外对象的B的子集)以确定B中的对象是否是还活着。因此,它将增量GC的问题从“所有对象”转移到“A和B中的所有对象”。在这种情况下,C根本不会得到处理。
这些标记技术适用于多组物体;它们不涉及单个对象保留。因此,除了卡片标记之外,对象还具有标记标记(在每个实例的标记字中),其包含对象是否已被标记/扫描/无论GC算法是什么。此标志中的各个位用于此目的,包括用于指示对象是否已标记的特殊位以及mark word implementation中特定于CMS收集器的位。但是,这些细节可能会随着版本的不同而有所不同,具体取决于使用的GC类型。
在任何情况下,这里的要点是卡片标记用于表示对象指向外部区域,并且实例被标记的方式使用特定于所使用的GC的不同技术。这不是一个或另一个的情况。
答案 1 :(得分:1)
我认为卡片标记算法和三色算法用于不同的目的: 卡标记用于跟踪从终身一代到年轻一代的参考。 三色算法用于从根集中找出哪些对象是可到达的。三色算法将通过卡片标记算法标识的对象集用作GC根。