我正在审查此演示文稿中的幻灯片: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是邪恶的
有人可以解释这个问题吗?
如果不是返回一个函数
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)
| 归档时间: |
|
| 查看次数: |
918 次 |
| 最近记录: |