说实话,我们需要快速浏览一下some测试您复制此代码的代码,但我对您所经历的情况有一个大概的了解。如果我错了并且您可以提供一些测试代码来证明这一点,请告诉我。
正如您似乎已经知道的那样,为了“清理”,Javascript 不想再引用想要释放的项目。
一个简单的例子:
// Currently not eligible for garbage
var myObj = {
data : 'test'
};
// Reference data inside myObj
// A unique identifier to myObj.data now exists
var myData = myObj.data;
// Whoops
myObj = 'something else';
// Because myData exists, so does data and can not be freed either, understandable
// This sounds simple and logical but most do not understand what is happening in the engine
// A relationship has been born between 'myData' and 'data' and as long as it exists, it is not eligible for garbage and remains in memory
console.log( myData );
您的代码可能比这更复杂,但这可能有助于解释如何在某个地方无法收集垃圾,因为作用域链可以跟踪引用。
考虑以下
function oops(text){
function doStuff(){
return text.toLowerCase();
}
return doStuff();
}
// 'doStuff' stays alive thanks to 'test' below.
var test = oops('closure');
功能doStuff
不会被垃圾收集,因为它正在被引用test
.
// You can see where this is headed. We have 2 references to the same 'doStuff' function object with separate unique identifiers now below.
var test2 = oops('closures...');
// This is now another unique identifier to 'doStuff'
var test3 = test2;
// doStuff survives yet still
test = 0;
test2 = 0;
// Now we let the function object of 'doStuff' be freed because there is no longer any references to it
test3 = 0;
这本质上是我们创建的内存泄漏。每次你打电话oops
您正在创建一个函数对象doStuff
具有唯一的标识符。
避免这种情况的一种方法可能是
function doStuff( text ){
return text.toLowerCase();
}
function oops( text ){
return doStuff();
}
var test = oops( 'closure' );
现在我们没有内存泄漏了。doStuff
正在invoked并不是created.
仔细查看您的代码,您会发现您可能在某处执行此操作。
如果你正在搞乱元素,我想你可能会这样,IBM 有一篇关于循环引用的好文章 http://www.ibm.com/developerworks/web/library/wa-memleak/你可能想看一下。
现在已经很晚了,其中一些内容尚未经过测试,但理论仍然存在,因此如果我拼写错误等,请告诉我,我明天可以为该页面的未来访问者查看。