【问题标题】:What is the reason for the leak?泄漏的原因是什么?
【发布时间】:2018-11-27 20:37:29
【问题描述】:

如何修复这段代码中的内存泄漏? 泄漏的原因是什么?

var theItem = null;
var replaceItem = function() {
    var priorItem = theItem;
    var writeToLog = function() {
        if (priorItem) {
            console.log("hi");
        }
    };
    theItem = {
        longStr: new Array(1000000).join('*'),
        someMethod: function() {
            console.log(someMessage);
        }
    };
};
setInterval(replaceItem, 1000);

【问题讨论】:

  • 如果您接受答案,请单击其左侧灰色“检查”按钮。您也可以通过点击附近的灰色三角形对答案进行投票。
  • 你在哪里找到这个代码?好像不是你自己写的。请链接源代码。

标签: javascript memory-leaks


【解决方案1】:

问题在于,每次调用 replaceItem 时都会增加对象链,因为内部的函数具有指向 priorItem 的指针,该指针指向先前函数调用的结果,该指针被“保存”在 theItem 全局变量中(外部函数)。因此,第 n 个函数调用具有指向第 (n-1) 个函数调用结果的指针-并且您以这种方式创建指针链-JS 垃圾收集器不会清理该链(除非您将 null 设置为它的开头-全局theItem,并停止调用函数)。

theItem 对象包含 someMethod,其中包含范围内的先前值 theItem(其中包含更多先前值......等等......)。

这将在this modified code 中更加明显 - 我们在 chrome 中调试它时:

我不知道您的目的是什么,但只需通过例如删除 replaceItem 函数体内的行 var priorItem = theItem; 来打破该链(并将功能更改 if (priorItem) { 保存为 if (theItem) {)。

【讨论】:

  • "那个函数里面有指向priorItem的指针" - 呃,只有writeToLog关闭了priorItem,并且它没有在对象中使用。对象的someMethod 仅关闭someMessage(未在任何地方声明...)?
猜你喜欢
  • 2011-08-11
  • 1970-01-01
  • 1970-01-01
  • 2020-04-17
  • 1970-01-01
  • 1970-01-01
  • 2017-04-28
  • 2012-06-17
  • 2017-02-15
相关资源
最近更新 更多