闭包如何造成内存泄漏?

Med*_*Man 8 javascript

我正在审查此演示文稿中的幻灯片:http://slid.es/gruizdevilla/memory

在其中一张幻灯片中,此代码显示它会创建内存泄漏:

var a = function () { 
   var smallStr = 'x',
   largeStr = new Array(1000000).join('x'); 

   return function (n) { 
        eval(''); //maintains reference to largeStr
        return smallStr; 
   }; 
}();
Run Code Online (Sandbox Code Playgroud)

闭包可能是内存泄漏的另一个来源.了解闭包中保留的引用.

并记住:eval是邪恶的

有人可以解释这个问题吗?

Mik*_*uel 6

如果不是返回一个函数

    eval('');
Run Code Online (Sandbox Code Playgroud)

你返回了一个传递其论点的人

    eval(n);
Run Code Online (Sandbox Code Playgroud)

然后有人可以调用a('largeStr')来获取数组,因此JavaScript解释器不能垃圾收集数组.

口译员可以意识到这一点

eval('');
Run Code Online (Sandbox Code Playgroud)

相当于

;
Run Code Online (Sandbox Code Playgroud)

但是大多数人都不够聪明,所以一旦他们看到eval他们停止允许GC关闭变量,只要闭合可以达到.


eval由于输入的性质,当无法有效访问封闭变量时,会出现内存泄漏:

eval('x' + (n-1));
Run Code Online (Sandbox Code Playgroud)

由于'x' + (n-1)无法生成一个引用largeStr无输入的JS字符串可能导致largeStr被使用但它仍然固定在内存中.


要看到整个事情的实际效果,请一起玩

 var f = (function () {
     var a = [,,,,,];
     return function (x) { return eval(x); };
   })();
 alert(f('a.length'));
Run Code Online (Sandbox Code Playgroud)