JavaScript闭包中的垃圾收集

Jib*_*ham 6 javascript closures garbage-collection

我需要一些帮助来解决它是如何工作的(或者就此而言).

  1. 在网页中,我为节点创建了一个click事件监听器.
  2. 在监听器中,我创建了一个随机类的实例,它将节点设置为自身内的属性.所以,如果var classInstance是实例,我可以像访问节点那样访问节点classInstance.rootNode.
  3. 当监听器触发时,我设置了一个ajax请求,保持classInstance关闭状态并传递ajax响应classInstance并使用它来修改其rootNode样式或内容或其他内容.

我的问题是,一旦我做与classInstance假设没有别的引用它,本身,它拥有闲来无事在自己的关闭,将它的垃圾收集处置?如果没有,我该如何标记它?

Eli*_*gem 6

为了回应@ Beetroot-Beetroot的疑虑(不可否认,我也有),我做了一些挖掘.我设置了这个小提琴,并使用chrome dev-tools的时间轴本文作为指导.在小提琴中,两个几乎相同的处理程序创建一个带有2个日期对象的闭包.第一个引用a,第二个引用ab.虽然在这两种情况下都只能a真正暴露(硬编码值),但第一个闭包使用的内存要少得多.无论是JIC(只是及时编译)还是V8的JS优化魔法,我都不能肯定.但是从我读过的内容来看,我会说V8的GC btst函数返回时会解除分配,而在第二种情况下则不能(返回时bar引用).我觉得这不是那么古怪,我一点都不会惊讶地发现FF甚至IE都会有类似的工作.为了完整性而添加了这个,也许是无关紧要的更新,因为我觉得google工具的google文档的链接是各种各样的附加价值.btst2


它有点依赖,作为一个简单的经验法则:只要你不能再引用classInstance变量,它就应该是GC,而不管它自己的循环引用.我已经测试了很多结构,类似于你在这里描述的结构.也许值得一看,
我发现闭包和内存泄漏并不常见或容易过去(至少,不再是).

但正如接受的答案所说:几乎不可能知道什么时候会泄漏什么代码.
再次阅读你的问题,我会说:不,你不会泄漏内存:classInstance变量不是在全局范围内创建的,而是传递给各种函数(因此也是各种范围).每次函数返回时,这些范围都会分解.classInstance如果它被传递到另一个函数/范围,则不会被GC.但是,只要引用的最后一个函数classInstance返回,该对象就会标记为GC.当然它可能是一个循环引用,但它是一个参考,不能从任何地方访问,但它自己的范围.
你不能真的称之为闭包:闭包发生在外部范围有某种形式的暴露时,这在你的例子中没有发生.

我在解释这样的东西时很垃圾,但回顾一下:

var foo = (function()
{
    var a, b, c, d;
    return function()
    {
        return a;
    }
})();
Run Code Online (Sandbox Code Playgroud)

GC将释放内存b,cd参考:它们已超出范围,无法访问它们......

var foo = (function()
{
    var a, b, c, d;
    return function()
    {
        a.getB = function()
        {
            return b;
        }
        a.getSelf = function()
        {
            return a;//or return this;
        }
        return a;
    }
})();
//some code
foo = new Date();//
Run Code Online (Sandbox Code Playgroud)

在这种情况下,b由于显而易见的原因,也不会得到GC.foo公开ab,a包含循环引用的对象在哪里.虽然一旦foo = new Date(),foo失去了任何参考a.当然,a仍然引用自己,但a不再暴露:它可以引用它喜欢的任何血腥.大多数浏览器都不关心GC ab.事实上,我已经检查过Chrome,FF IE8所有GC上面的代码完美......不用担心.