一个JS内存泄露实例分析

Posted 牛太黑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个JS内存泄露实例分析相关的知识,希望对你有一定的参考价值。

在看JS GC 相关的文章时,好几次看到了下面这个设计出来的例子,比较巧妙,环环相扣。
 
var theThing = null;
var replaceThing = function () {
    var originalThing = theThing;
    var unused = function () {
        if (originalThing)
            console.log("hi");
    };
    theThing = {
        longStr: new Array(10000).join(‘*‘),
        someMethod: function () {
            console.log(1111);
        }
    };
};
 
setInterval(replaceThing, 1000);

 

由于 V8 GC 的关键是 root 级对象,因此内存泄露基本上都是由于 root 级引用没有被释放导致的。
 
上面代码中的 root 主要有两个,一个是 theThing,另一个是 replaceThing 运行时的调用栈。这里的内存泄露主要是 theThing。
 
总体来说是因为,root 级对象 theThing 持有了 replaceThing1 内部对象的引用,并且在下一次把引用转交给了 replaceThing2,然后持有了 replaceThing2 的内部引用。
详细一点:theThing 持有了 longStr 和 someMethod 的引用,由于 someMethod 这个闭包会保留它的 context,因此 replaceThing 整体被保留了,于是 unused 被保留;而 unused 又持有了 originalThing 的引用,因此 originalThing 持有了 由 theThing 转交过来的前一个 setInterval 时的 someMethod 和 longStr。 一次又一次 setInterval 下去,longStr 和 someMethod 就被串了起来。
 
图解:
 
setInterval1:
 
  originalThing           theThing
           |                           |
         null             someMethod1
 
 
setInterval2:
 
  originalThing           theThing
          |                            |
someMethod1    someMethod2   --unused--> replaceThing1 --> someMethod1
 
 
技术分享
 
 
 
 
 
 
 
 
 
 

以上是关于一个JS内存泄露实例分析的主要内容,如果未能解决你的问题,请参考以下文章

如何用Java编写一段代码引发内存泄露

如何查看和调试动态链接库的内存泄露

如何用Java编写一段代码引发内存泄露

JS内存泄漏 和Chrome 内存分析工具简介(摘)

PHP CURL内存泄露的解决方法

为啥这段代码会泄露? (简单的代码片段)