我们手动需要清除闭包中的未引用变量吗?

Jon*_*han 6 javascript memory-leaks

我正在阅读这篇关于内存泄漏的文章(http://javascript.info/tutorial/memory-leaks#memory-leak-size),其中提到这是一个内存泄漏:

function f() {
    var data = "Large piece of data";

    function inner() {
        return "Foo";
    }

    return inner;
}
Run Code Online (Sandbox Code Playgroud)

JavaScript解释器不知道内部函数可能需要哪些变量,所以它保留了所有内容.在每个外部词汇环境中.我希望,新的口译员会尝试优化它,但不确定他们的成功.

文章建议我们data = null在返回内部函数之前需要手动设置.

今天这是否适用?或者这篇文章过时了吗?(如果它已经过时,有人可以指出我有关当前陷阱的资源)

小智 5

现代引擎不会在外部范围内维护未使用的变量.

因此,如果data = null在返回内部函数之前设置,则无关紧要,因为内部函数不依赖于("close over")data.

如果内部函数确实依赖于 - data也许它返回它 - 那么设置data = null肯定不是你想要的,因为那样,它将是null而不是它的原始值!

假设内部函数确实依赖于data,那么是的,只要inner被指向(引用)某事,那么data必须保持值的值.但是,这就是你想要的!如何在没有它的情况下提供可用的东西?

请记住,在某些时候,保存返回值的变量f()本身将超出范围.此时,至少f()再次调用,data将被垃圾收集.

一般规则是您不需要担心内存和JavaScript泄漏.这就是GC的重点.垃圾收集器可以很好地识别需要什么和不需要什么,并保持前者和垃圾收集后者.

您可能需要考虑以下示例:

function foo() {
  var x = 1;
  return function() { debugger; return 1; };
}

function bar() {
  var x = 1;
  return function() { debugger; return x; };
}

foo()();
bar()();
Run Code Online (Sandbox Code Playgroud)

并在Chrome devtools变量窗口中检查其执行情况.当调试器在内部函数中停止时foo,请注意它x不作为局部变量或闭包存在.出于所有实际目的,它不存在.

当调试器在内部函数中停止时bar,我们看到变量x,因为它必须被保留以便可以被访问才能被返回.

今天这是否适用?或者这篇文章过时了吗?

不,它没有,是的,它是.这篇文章已有四年历史,这是网络世界的一生.我无法知道jQuery是否仍然存在漏洞,但如果是这样,我会感到惊讶,如果是这样的话,有一种简单的方法可以避免它们 - 不要使用jQuery.文章作者提到的与DOM循环相关的漏洞和现代浏览器中不存在事件处理程序,我的意思是IE10(更可能是IE9)及更高版本.如果你真的想了解内存泄漏,我建议你找一个更新的参考资料.实际上,我建议你主要不要担心内存泄漏.它们仅在非常特殊的情况下发生.由于这个确切的原因,现在很难在网上找到很多关于这个主题的内容.这是我找到的一篇文章:http://point.davidglasser.net/2013/06/27/surprising-javascript-memory-leak.html.