Javascript内存泄漏:分离的DOM树

时间:2013-06-03 16:47:22

标签: javascript jquery google-chrome-devtools

我注意到浏览器的内存在我处于某种形式时开始增加(这在任务管理器中很明显)。在IE 9中,在使用一段时间后,这很容易超过500MB,而chrome则更具弹性(使用相同的测试可达到200MB)。

我正在使用chrome开发人员工具来调试此问题。我注意到有大量的Detached DOM树:

detached dom tree screenshot

我假设这可以确认存在内存泄漏。这是对的吗? 其次,我需要找出如何确定问题的根本原因。我知道您应该使用保留树来识别阻止这些物品被回收的原因。但我无法找到如何使用保留树。例如,上面屏幕截图中的保留树是什么意思?

非常感谢任何协助。

2 个答案:

答案 0 :(得分:26)

编写引用DOM元素的代码时,请记住许多注意事项。但这一切基本上归结为几个简单的观点 -

一个。在本地功能中,请始终清除参考

var menu = $('body #menu');
// do something with menu
 .
 .
 .
 menu = null;

湾永远不要将引用存储为元素数据.data()

的一部分

℃。尽量不要在闭包/内联处理程序中使用DOM引用,而是传递标识符

    function attachClick(){
      var someDiv = $('#someDiv');

      someDiv.click(function(){
         var a = someDiv....;
         //Wrong. Instead of doing this..
      });


      someDiv.click(function(){
         var a = $('#someDiv');
         //Pass the identifier/selector and then use it to find the element
      });       


      var myFunc = function(){
         var a = someDiv;
         //using a variable from outside scope here - big DON'T!             
      }
    }

是的,人们可以争辩说,搜索元素可以减慢页面速度,但与性能相比,延迟是非常小的。在大型单页面应用程序中。因此,只有在权衡利弊后才能使用#3。 (在我的案例中它确实有很大帮助)

<强>更新

d。避免使用匿名函数 - 在分析/查看堆快照时,命名事件处理程序和本地函数将对您有所帮助。

答案 1 :(得分:2)

看起来您的代码会创建许多DOM子树,并通过javascript保留对它的引用。您需要从Detached dom树中选择一个元素。根据快照,您应该选择Text元素。并查看保留树。

此树显示保持对象存活的所有路径。至少一条路径(通常是最短路径)将引导您进入窗口对象。如果您熟悉代码,那么您可以轻松找到该路径中必须删除的对象,但事实并非如此。路径中可以有许多这样的对象。距离最小的物体更有趣。