Knuth GC 堆栈溢出预防算法 - 它是如何工作的?

Knuth GC stack overflow prevention algorithm - how does it work?

我正在阅读 垃圾收集。 Algorithmis for Automatic Dynamic Memory Management 一书,并尝试写一篇关于它的博客 post。我专注于标记清除章节,作者在该章节讨论了使用 辅助堆栈 ,以避免标记清除溢出 'normal' 堆栈。到目前为止一切顺利。

在辅助栈溢出的小节中,直接引用了一句:

Knuth handles overflow by treating the marking stack circularly, stacking pointers to nodes modulo h, where h is the fixed size of the stack. This means that older branch-point information on the stack is overwritten when the stack index grows larger than h. Consequently, the stack may become empty before the marking process is complete as the live graph below a node whose pointer on the mark stack has been overwritten may not have been marked.

据我了解,GC 过程从根开始遍历对象,添加指向辅助堆栈的指针。这很简单。但是,这个堆栈有一个特定的大小(这是为了防止溢出)。当这种情况发生时,向该堆栈添加新指针将大于限制(导致 SO),现有条目将被丢弃以为新条目腾出空间。我是这么理解的。

我的问题是这句话:

Consequently, the stack may become empty before the marking process is complete as the live graph below a node whose pointer on the mark stack has been overwritten may not have been marked.

英语不是我的母语,这里讨论的话题很重要,但我只需要一个答案——根据上面的句子,这个机制是如何工作的?为什么堆栈应该被清空,而不是保持常量 <= h 个条目?

PS。在 Jones - 'The Garbage Collection Handbook' 的第二本书中没有关于上述主题的文字,所以不幸的是我无法比较 phrasing/preesntation.

我认为它完全符合您的想法。有一个大小为 3 的堆栈,我在上面写了 A、B、C 和 D。 D 覆盖了 A。因此,A 永远不会被查看。

看你怎么实现限长栈,你写D之后,栈长可能是3,也可能是4。但是无论哪种情况,当你回到栈长为0时,你还没看A.