检测Chrome的DevTools中泄漏的DOM节点

时间:2014-06-11 00:18:26

标签: javascript memory-leaks google-chrome-devtools

我正在尝试使用Chrome Dev Tools来分析我的应用程序上的内存使用情况并检测泄露的DOM节点,并对我看到的一些行为感到困惑。根据{{​​3}},如果我创建DOM节点然后正确释放它们,该工具应该响应一个“Nodes”计数器,该计数器将重置为其基线:

  

但是如果预计行动序列不会导致任何保留的内存,并且DOM节点数不会下降回到您开始的基线,那么您有充分的理由怀疑存在泄漏。

方法:我使用了Chrome profiling docs的变体,修改后在节点内创建大字符串。

<html>
<head>
  <script>
  var leakedNodes = [];

  var largeStr = new Array(1000000).join('x');

  function createNode(text) {
    var div = document.createElement("div"),
      innerDiv = document.createElement("div"),
      textNode = document.createTextNode(text + " - " + new Date().toTimeString() + "-" + largeStr);
    innerDiv.appendChild(textNode);
    div.appendChild(innerDiv);
    return div;
  }

  function createLeakedNodes() {
    var i;
    for (i = 0; i < 200; i++) {
      leakedNodes.push(createNode("Leaked:" + i));
    }
  }

  function createGCNodes() {
    var i;
    for (i = 0; i < 200; i++) {
      createNode("Collected:" + i);
    }
  }

  function createNodes() {
    createLeakedNodes();
    createGCNodes();
  }

  function clearLeaks() {
    leakedNodes = null;
  }
  </script>
</head>

<body>
  <button onclick="createNodes()">Create</button>
  <button onclick="clearLeaks()">Clear Leaks</button>
</body>

</html>

我在未启用扩展程序的隐身标签页面中启动该页面,启动开发工具,然后启动时间轴。我按下“创建”按钮三次,然后按“清除泄漏”按钮一次,然后单击分析器中的“收集垃圾”按钮强制GC,等待GC完成,然后停止时间线。

我查看了探查器中的“节点”计数器,并且在我按下“创建”按钮,然后在我单击“清除泄漏”按钮之后或之后,预计会看到它爬升的每一次我强迫GC。然而,我所看到的是图表爬升,但从未下降。

Screenshot of Nodes counter

我对图表行为的理解是否不正确,或者节点是否合法地未被释放?如果是后者,上面的代码会导致泄漏,为什么相关内存显然是GCd符合预期?

2 个答案:

答案 0 :(得分:3)

如果处理对数组的引用,似乎不会破坏对DOM节点的引用。但是如果你将数组的长度设置为零,那么数组中的所有元素都将被处理掉(因此所有对DOM元素的引用),然后垃圾收集器就可以完成它的工作并释放内存。 / p>

function clearLeaks() {
    leakedNodes.length = 0;
  }

我通过做一些研究并使用你的示例代码得到了这个结果:)。

答案 1 :(得分:1)

我认为Chrome开发工具中存在与DOM节点数相关的错误,如here所述。 在canary中分析代码确实会减少DOM数量。