【问题标题】:why does this js function cause a memory leak?为什么这个js函数会导致内存泄漏?
【发布时间】:2017-07-19 00:43:46
【问题描述】:

我不明白这段代码是如何导致内存泄漏的。

var theThing = null;
var replaceThing = function () {
    var originalThing = theThing;
    var unused = function () {
        if (originalThing)
            console.log("hi");
    };
    theThing = {
        longStr: new Array(1000000).join('*'),
        someMethod: function () {
            console.log(someMessage);
        }
    };
};
setInterval(replaceThing, 1000);

如果我在函数replaceThing 的末尾设置originalThing 为null,一切都会好起来的。但是这里没有看到引用循环,也不知道为什么这些闭包不能释放。

v8 GC 不使用标记扫描吗?如果我把这些代码放到 IIFE 中,内存泄漏仍然存在。但是根上下文如何才能到达这些变量和函数呢? 我使用 chrome 测试了这些代码。现在我对 GC 在 Closure 上的工作方式感到困惑。

【问题讨论】:

    标签: javascript memory-leaks garbage-collection


    【解决方案1】:

    https://www.ibm.com/developerworks/web/library/wa-memleak/

    因为内部函数持有对外部函数变量的引用,作用域对象...不会被垃圾回收。

    【讨论】:

    • 你的意思是someMessage没有找到吗?但是我已经尝试将其替换为字符串'someMessage'。内存泄漏仍然存在
    • 谢谢,我明白了,但我还有一些疑问。首先,我明白了深层嵌套上下文是如何产生的,但是为什么这个上下文不能释放,因为在第一个上下文中,@ 987654325@等于null,如果theThing不是全局的,在我调用replaceThing之后,theThing将不再使用,应该用someMethod触发。其次,当我删除unused时,泄漏似乎消失了。
    • 我找到了一个很好的资源(向下滚动到闭包):ibm.com/developerworks/web/library/wa-memleak
    • 看到了这句话,但我认为是清单4的结论。在清单4中,内部函数已经返回。x持有内部函数的引用,而内部函数持有外层函数的a,所以当外层函数结束时,作用域对象仍然存在于内存中。但是x('inner x')之后发生的事情,如果x不是全局的,最后所有这些都无法访问。
    【解决方案2】:

    在第一次调用 originalThing 被赋值为 null 之后,theThing 成为对新对象的引用,第二次和后续调用 originalThing 分配对对象的引用,然后再次 theThing 成为引用到新对象,但originalThing 将链接到前一个对象

    【讨论】:

    • 是的,但是为什么不能触发这些变量。如果GC使用标记扫描,所有这些都无法达到
    • 因为对对象的一个​​引用仍然存在
    • 但是如果不再需要持有对 object1 的引用的对象呢?假设,obj1,obj2,下一个持有前一个,obj2 不能因为 obj1 而被触发,但是如果obj1 也不需要,所有这些都应该被解雇。第一个originalThing 为null,下一个拥有前一个的引用,但是当不再需要最后一个时,为什么不解雇他们。我误解你的意思了吗?
    • 好吧,让我们订购吧。我们已经在theThing 外部声明了变量然后我们在replaceThing 内部创建了一个函数并创建了originalThing 一个指向外部theThing 的链接。然后我们创建一个unused,其中...if (originalThing)...=> 引用`theThing` 进一步更改theThing 链接到一个新对象,但仍保留在`unused` 链接到前一个对象theThing,虽然我们会丢失和replaceThing GC 之外的上下文以及对象在完成 replaceThing 后不干净 unused@
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 2020-10-26
    相关资源
    最近更新 更多