为什么在并发GC跟踪中需要SATB算法?



在并发 GC 中说,在跟踪开始时,对象 A 在 根集。对象 A 指 B 和 C,B 和 C 在 堆。在追踪过程中,突变子会改变 A 对 C 的引用。所以 C 已死。SATB算法说C将被保存在记忆中 由作家屏障设置。但是如果我们没有在记住集中保存 C, 可能会发生 2 种情况:

  1. 突变器更改为 C 发生在跟踪线程之前 到达C。那么当跟踪线程不会到达C时,C是 已经死了。在这一轮追踪中,活集只包括B。

  2. 突变器更改为 C 发生在跟踪线程之后 到达 C(但在下一轮跟踪之前)。然后 跟踪线程能够到达 C。在这一轮的追查中, 现场集包括B和C.C将在下一轮收集 的追踪。

因此,在上述 2 种情况下,我们总是可以在第一轮跟踪或下一轮跟踪中在没有 SATB 的情况下获得正确的集合 B。

所以我的问题是:在上述情况下,SATB 根本不需要 保持并发 GC 正确。为什么我们要费心保存快照 在作家障碍?

您的案例对于并发收集器的讨论并不真正有趣。C 是死的,无论收集器在当前周期还是下一个周期中注意到它的不可访问性都没有什么区别,因为 GC 无论如何都不保证立即释放内存。

有趣的案例是关于活体的,因为这些是那些不想被意外释放的物体。当突变器获取尚未标记的对象(现有或新创建的对象)并将其放入可标记可访问对象的字段中时,很容易发生这种情况。由于保持对象已经标记为收集器,因此它不会访问另一个对象,因此写入屏障必须以某种方式提供帮助。SATB就是其中一种方式。

最新更新