使用jQuery和内存泄漏

时间:2011-03-11 02:30:45

标签: javascript memory-leaks closures jquery

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

  1. 当我绑定(使用.bind(...))时,如果我离开页面/刷新以避免内存泄漏或jQuery是否为我删除它,我是否必须取消绑定它们(.unbind())?

  2. 关于闭包,我读到如果使用不当会导致内存泄漏。如果我做了以下的事情:

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

    doStuff($(“*”));

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

    提前致谢。

    编辑:我有另一个类似于问题2的案例(我猜这是第3部分)。

    1. 如果有这样的话:

      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”));

    2. 上面有3个案例,我想知道哪个方法(或所有方法)会产生内存泄漏。另外我想知道哪种方法是首选方法(通常我使用的是案例2)或更好的做法(或者如果这些方法不好也会更好?)。

      再次感谢!

4 个答案:

答案 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等。

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

希望这有帮助