这个js代码如何泄漏内存?

时间:2016-11-17 09:42:03

标签: javascript memory-leaks garbage-collection

我一直在阅读js最佳做法和常见错误,我从https://www.toptal.com/javascript/10-most-common-javascript-mistakes

中看到了这段代码
var theThing = null;
var replaceThing = function () {
    var priorThing = theThing;  // hold on to the prior thing
    var unused = function () {
        // 'unused' is the only place where 'priorThing' is referenced,
        // but 'unused' never gets invoked
        if (priorThing) {
            console.log("hi");
        }
    };
    theThing = {
        longStr: new Array(1000000).join('*'),  // create a 1MB object
        someMethod: function () {
            console.log(someMessage);
        }
    };
};

我尝试将此代码输入控制台并多次调用replaceThing()并且确实如此,即使在GC之后,Chrome任务管理器中的内存使用率也会上升。

闭包unused保留对priorThing的引用,从而使其不符合GC的条件。但是:

  1. 执行priorThing = theThing时,unused关闭中的引用是否也会更改为theThing
  2. 即使#1不是这样的情况,当unused的执行完成时,变量replaceThing是否应该超出范围?

1 个答案:

答案 0 :(得分:1)

是有内存泄漏。这是因为在Javascript中实现闭包的方式。每个函数对象都有一个链接到表示其词法范围的字典样式对象。 IF A VARIABLE IS USED IN ONE CLOSURE, IT ENDS UP IN THE LEXICAL SCOPE SHARED BY ALL OTHER CLOSURES IN THAT SCOPE。在这种情况下,我们在同一范围内有两个闭包theThingunused。在priorThing中使用unused,现在priorThing是闭包中的变量,而unused未被调用,则意味着priorThing也在theThing关闭的范围。因此priorThing返回后,replaceThing将不会收集垃圾。

1)执行priorThing = theThing时,旧的theThing值会存储到priorThing,因此unused指的是旧的theThing而不是新创建的<{1}} < / p>