2011-03-11 122 views
3

我已经使用jQuery了几个月,并阅读了几天的JavaScript内存泄漏。 我有一个关于内存泄漏和jQuery两个问题:使用jQuery和内存泄漏

  1. 当我绑定(使用.bind(...))我一定要拆散他们(.unbind()),如果我离开这个页面/刷新避免内存泄漏或jQuery为我删除它们?

  2. 关于关闭,我读了他们可能导致内存泄漏,如果使用不正确。如果我做了如下操作:

    函数doStuff(objects){//对象是一个容纳DOM对象数组的jQuery对象 var textColor =“red”; (function)(){ $(this).css(“color”,textColor); }); }

    doStuff($(“*”));

我知道,上面的代码是愚蠢的(更好/更简单[R这样做的方法),但我想知道这是否会导致。每次循环引用/关闭的问题,它是否会导致内存泄漏。如果它确实导致内存泄漏,我将如何重写它(通常类似的方法)以避免内存泄漏?

在此先感谢。

编辑:我有另一个类似问题2的情况下(我想这部分3)。

  1. 如果有这样的事情:

    函数doStuff(对象){// IFRAME对象 VAR文字颜色= “红色”;

    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.,否,当离开页面时,您绝对不需要.unbind()。我不完全确定两个。

1

1)否。浏览器清除页面加载之间的所有内容。

2)在目前的形式中,不会有内存泄漏,因为jquery的.each()函数没有绑定任何东西,所以一旦它的执行完成,它传递的匿名函数就不再可用了,因此它的环境关闭(即关闭作为一个整体)也无法到达。所以垃圾收集引擎可以清理所有东西 - 包括对objects的引用。

然而,如果代替.each()你有一些东西是无害的,就像$('div:eq(0)').bind()(我想强调的是,它不需要到大objects变量的引用,以至于它甚至是一个单一的元素无关),然后由于发送给.bind()的匿名函数关闭了objects变量,因此它将保持可访问状态,因此不会收集垃圾,从而导致内存泄漏。

避免此问题的一个简单方法是在执行函数结束时执行objects = null;

我应该注意到我并不熟悉JS垃圾收集引擎,所以有可能有合理的智能优化。例如,可以检查匿名函数是否尝试访问任何关闭的变量,如果不是,它可能会将它们传递给垃圾回收器,这可以解决问题。

要进一步阅读,请查找对javascript的内存模型的引用,特别是环境模型和静态绑定。

0

关于1,有时你必须释放你的资源,特别是当你有循环引用和使用Internet Explorer时(因为有一些错误,因为理论上你不应该这么做);)谷歌地图有一个函数他们的v2,以防止我们不得不呼吁document.onunload(GUnload)。

关于2,您没有循环引用。它消耗大量的内存,因为this必须有自己的执行上下文以访问textColor等等。

循环引用是在对象引用自身或闭包自行调用时实现的。也许还有其他情况..

希望这有助于

+0

如果没有必要的循环引用,可能会导致封闭泄漏 – davin 2011-03-11 03:00:02

1

有一些细微的泄漏模式,你甚至可能不会承认。看看我前一段时间提到的有关类似问题的一个问题 jQuery 1.5 Memory leak in IE8

如果在引用dom节点的对象周围创建一个闭包,会产生一个泄漏的引用循环,不幸的是,它不能被简单地纠正解除绑定。您将不得不将对象中的DOM节点的引用设置为null。

+0

我不同意,只是因为有一个对象引用了一些DOM节点,并不意味着有泄漏。在这种特殊情况下,在函数执行结束时不再可以访问对象,因此有资格进行垃圾回收==>没有内存泄漏。 – davin 2011-03-11 03:06:52

+0

理论上,情况就是这样。但是,在某些情况下,一旦在IE(object-> node-> eventHandler-> object)中创建了一个引用循环,它就永远不会被释放,即使您将eventHandler(object-> node X eventHandler-> object )。请在我提供的链接中尝试jsFiddle并观看taskManager – jordancpaul 2011-03-11 03:11:09

+0

在这里的代码中没有循环引用,所以虽然在这种情况下您可能是正确的,但在此处不适用。 – davin 2011-03-11 03:14:19