Javascript/垃圾收集器中的循环引用

Javascript/垃圾收集器中的循环引用,javascript,memory-leaks,garbage-collection,circular-reference,Javascript,Memory Leaks,Garbage Collection,Circular Reference,有人能详细解释一下Javascript引擎如何处理循环引用吗?浏览器甚至node.js之间有很大的区别吗 我说的是对象中的显式back-/next引用。例如: var objA = { prop: "foo", next: null }; var objB = { prop: "foo", prev: null }; objA.next = objB; objB.prev = objA; 好了。如果我们做一个console.log(objA)我们可以看到我们

有人能详细解释一下Javascript引擎如何处理循环引用吗?浏览器甚至node.js之间有很大的区别吗

我说的是对象中的显式back-/next引用。例如:

var objA = {
    prop: "foo",
    next: null
};

var objB = {
    prop: "foo",
    prev: null
};

objA.next = objB;
objB.prev = objA;
好了。如果我们做一个
console.log(objA)
我们可以看到我们创建了一个无限链。 最大的问题是,这不好吗?未明确清理时是否会导致内存泄漏

那么我们必须这样做吗

objA.next = null;
objB.prev = null;

或者垃圾收集器会在这样的星座上照顾我们吗?

任何半体面的垃圾收集器都会处理循环

只有在进行简单的引用计数时,周期才是一个问题

大多数垃圾收集器不进行ref计数(既因为它不能处理循环,也因为它效率低下)。相反,他们只是从“根”(通常是全局变量和基于堆栈的变量)开始,跟踪他们能找到的每一个引用,并将所有能找到的标记为“可到达”

然后,它们简单地回收所有其他内存

循环是没有问题的,因为它们只是意味着同一个节点将被多次访问。第一次之后,该节点将被标记为“可访问”,因此GC将知道它已经存在,并跳过该节点

基于引用计数的更原始的GC通常实现检测和中断循环的算法

简而言之,这不是你必须担心的事情。 我似乎记得IE6的Javascript GC实际上无法处理循环(我可能错了,我读过它已经有一段时间了,我接触IE6已经很久了),但在任何现代实现中,这都不是问题

垃圾收集器中的全部要点是抽象出内存管理。如果你必须自己做这项工作,你的GC就坏了


有关现代垃圾收集以及使用的标记和清除算法的更多信息,请参阅。

这有什么不对吗?@Sandro再次阅读我的答案。:)一个正常的GC可以很好地处理循环。所有比IE6更新的东西都可以被认为是正常的。如果您需要支持IE6,那么您必须担心它对循环的处理不好。显然,谷歌的指南是在这样一种假设下编写的,即必须支持这样的坏浏览器,因此它们必须跳转到一些额外的环中。@Sandro在这个例子中有一些特殊的东西:DOM元素是循环引用的一部分。通常,在关闭页面之前,您会泄漏内存。但是,如果我没记错的话,IE并不总是在您离开时删除对DOM的引用。(很明显,这样做打破了一些页面?)道格拉斯·克罗克福德(Douglas Crockford)也是这样。我认为现在我们可以认为它与大多数Web应用程序无关。