在Javascript /垃圾收集器中的循环引用 [英] Circular references in Javascript / Garbage collector

查看:117
本文介绍了在Javascript /垃圾收集器中的循环引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以详细解释Javascript引擎如何处理循环引用?浏览器和node.js之间有很大的区别吗?



我在说的是对象中明确的后/后引用。例如:

  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;

或者垃圾收集器是否会照顾我们这样的星座?

$ b $

如果你是一个循环,循环只是一个问题。做很幼稚的引用计数。

大多数垃圾收集器都不会进行重新计数(因为它无法处理循环,并且效率低下)。相反,他们只是遵循他们可以找到的每个参考,从根(通常是全局变量和基于堆栈的变量)开始,并标记他们可以找到的所有可访问。



<然后他们只需回收所有其他内存。

循环没有问题,因为它们意味着同一个节点将被多次访问。在第一次之后,节点已经被标记为可达了,所以GC会知道它已经在那里了,并且跳过节点。



更多基于引用计数的原始GC通常实现算法来检测和打破周期。

总之,这不是您必须担心的问题。
我似乎记得,IE6的Javascript GC实际上没有处理周期(我可能错了,自从我读了它已经有一段时间了,自从我触及IE6以来已经很长时间了),但是在任何现代实现中,这是没有问题的。


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

请参阅 MDN 了解更多关于现代垃圾收集和使用的标记和扫描算法的信息。


Can somebody explain in detail how Javascript engines deal with circular references ? Is there a big difference between browsers or even node.js ?

What I'm talking about is an explicit back-/next reference within objects. For instance:

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

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

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

There we go. If we do a console.log( objA ) we can see that we created an infinite chain. The big question is, is this bad ? Does it create memory leaks when not explicitly cleaned?

So do we have to

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

or will the garbage collectors take care of us on constellations like this?

解决方案

Any half-decent garbage collector will handle cycles.

Cycles are only a problem if you do naive reference counting.

Most garbage collectors don't do ref-counting (both because it can't handle cycles, and because it's inefficient). Instead, they simply follow every reference they can find, starting from "roots" (typically globals and stack-based variables), and mark everything they can find as "reachable".

Then they simply reclaim all other memory.

Cycles are no problem because they just mean that the same node will be reached multiple times. After the first time, the node will be marked as "reachable" already, and so the GC will know that it's been there already, and skip the node.

Even more primitive GC's based on reference-counting typically implement algorithms to detect and break cycles.

In short, it's not something you have to worry about. I seem to recall that IE6's Javascript GC actually failed to handle cycles (I could be wrong, it's been a while since I read it, and it's been much, much longer since I touched IE6), but in any modern implementation, it is no problem.

The entire point in a garbage collector is to abstract away memory management. If you have to do this work yourself, your GC is broken.

See MDN for more information on modern garbage collection and the mark-and-sweep algorithms that are used.

这篇关于在Javascript /垃圾收集器中的循环引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆