我已经使用jQuery超过几个月,并阅读了几天的Javascript内存泄漏。 我有两个关于内存泄漏和jQuery的问题:
当我绑定(使用.bind(...))时,如果我离开页面/刷新以避免内存泄漏或jQuery是否为我删除它,我是否必须取消绑定它们(.unbind())?
关于闭包,我读到如果使用不当会导致内存泄漏。如果我做了以下的事情:
function doStuff(objects){//对象是一个包含DOM对象数组的jQuery对象 var textColor =“red”; objects.each(函数(){ $(this).css(“color”,textColor); }); }
doStuff($(“*”));
我知道上面的代码是愚蠢的(更好/更简单的方法)但是我想知道这是否会导致.each的循环引用/闭包问题以及是否会导致内存泄漏。如果它确实导致内存泄漏,我将如何重写它(通常类似的方法)以避免内存泄漏?
提前致谢。
编辑:我有另一个类似于问题2的案例(我猜这是第3部分)。
如果有这样的话:
function doStuff(objects){// iframe对象 var textColor =“red”;
function innerFunction()
{
$(this).contents().find('a').css("color", textColor );
}
objects.each(function(){
//I can tell if all 3 are running then we
//have 3 of the same events on each object,
//this is just so see which method works/preferred
//Case 1
$(this).load(innerFunction);
//Case 2
$(this).load(function(){
$(this).contents().find('a').css("color", textColor );
});
//Case 3
$(this).load(function(){
innerFunction();
});
});
}
doStuff($(“iframe”));
上面有3个案例,我想知道哪个方法(或所有方法)会产生内存泄漏。另外我想知道哪种方法是首选方法(通常我使用的是案例2)或更好的做法(或者如果这些方法不好也会更好?)。
再次感谢!
答案 0 :(得分:1)
1)否。浏览器会在页面加载之间清除所有内容。
2)在当前形式中不存在内存泄漏,因为jquery的.each()
函数没有绑定任何东西,所以一旦执行完成,它传递的匿名函数就不再可以访问了,因此它关闭的环境(即整个封闭)也是无法到达的。因此垃圾收集引擎可以清理所有内容 - 包括对objects
的引用。
但是,如果代替.each()
你有一些无害的东西,比如$('div:eq(0)').bind()
(我试图强调它不必是对大objects
变量的引用,它甚至是一个不相关的元素),然后由于发送到.bind()
的匿名函数关闭了objects
变量,它将保持可访问状态,因此不会进行垃圾回收,从而导致内存泄漏。
避免此问题的一种简单方法是在执行函数结束时objects = null;
。
我应该注意到我不熟悉JS垃圾收集引擎,因此可能存在相当智能的优化。例如,可以检查匿名函数是否尝试访问用它关闭的任何变量,如果没有,它可能会将它们传递给垃圾收集器,这将解决问题。
如需进一步阅读,请查找对javascript内存模型的引用,特别是环境模型和静态绑定。
答案 1 :(得分:1)
有些细微的泄漏模式甚至无法识别。看看我前一段时间提出的关于类似问题的问题 jQuery 1.5 Memory leak in IE8
如果在引用dom节点的对象周围创建一个闭包,则会产生一个泄漏的引用循环,不幸的是,它无法通过简单的解除绑定来纠正。您必须将对象中DOM节点的引用设置为null。
答案 2 :(得分:0)
关于1.,不,你离开页面时绝对没有.unbind()
。我不完全确定两个。
答案 3 :(得分:0)
大约1,有时你必须释放你的资源,特别是当你有循环引用和使用Internet Explorer时(因为一些错误,因为理论上你不应该这样做);)谷歌地图有一个功能在他们的v2以防止我们必须调用document.onunload
(GUnload)。
关于2,您没有循环引用。它消耗了大量内存,因为this
必须有自己的执行上下文才能访问textColor
等。
当对象引用自身或闭包调用自身时,实现循环引用。也许还有其他情况......
希望这有帮助