用读屏障实现并发转移

用读屏障实现并发转移

用读屏障实现并发转移 #

CMS 算法和 G1 算法都使用了 write barrier 来保证并发标记的完整性,防止漏标现象。ZGC 的并发标记也不例外。除此之外,ZGC 提升效率的核心关键在于并发转移阶段使用了 read barrier。

当应用线程去读一个对象时,GC 线程刚好正在搬移这个对象。如果 GC 线程没有搬移完成,那么应用线程可以去读这个对象的旧地址;如果这个对象已经搬移完成,那么可以去读这个对象的新地址。那么判断这个对象是否搬移完成的动作就可以由 read barrier 来完成。 上图中,对象 a 和对象 b 都引用了对象 foo,当 foo 正在拷贝的过程中,应用线程 A 可以访问旧的对象 foo 得到正确的结果,当 foo 拷贝完成之后,应用线程 B 就可以通过 read barrier 来获取对象 foo 的新地址,然后直接访问对象 foo 的新地址。

如果这里只用 write barrier 是否可行?当 foo 正在拷贝的过程中,应用线程 A 如果要写这个对象,那么只能在旧的对象 foo 上写,因为还没有搬移完成;如果当 foo 拷贝完成之后,应用线程 B 再去写对象 foo,是写到 foo 的新地址,还是旧地址呢?

如果写到旧地址,那么对象 foo 就白搬移了,如果写到新地址,那么又和线程 A 看到的内容不一样?所以使用 write barrier 是没有办法解决并发转移过程中,应用线程访问一致性问题,从而无法保证应用线程的正确性。因此,为了实现并发转移,ZGC 使用了 read barrier。

Viewpoint #

From #

23 | Pauseless GC:挑战无暂停的垃圾回收