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

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

问题描述

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

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;

我们走了.如果我们执行一个 console.log(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?

所以我们必须

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.

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

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.

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

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

简而言之,这不是您必须担心的事情.我似乎记得 IE6 的 Javascript GC 实际上未能处理循环(我可能是错的,我已经有一段时间没有阅读它了,而且自从我接触 IE6 以来已经很久了),但在任何现代实现中,它都不是问题.

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.

垃圾收集器的全部意义在于抽象出内存管理.如果你必须自己做这项工作,你的 GC 就坏了.

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天全站免登陆