【问题标题】:Understanding memory leaks in Chrome and the 'Uncovering DOM leaks' example了解 Chrome 中的内存泄漏和“发现 DOM 泄漏”示例
【发布时间】:2015-11-23 09:05:14
【问题描述】:

在 Chrome 文档的 this page 上,他们给出了以下代码示例:

function start()
{
    var p = document.getElementById("p");
    detached = document.createElement("div");
    p.appendChild(detached);
    p.removeChild(detached);
    //Fill up detached with a bunch of garbage data
}

然后他们声称这是因为

..一个 DOM 节点从树中分离出来,但它仍然保存引用脚本数据的 DOM 包装器对象,有效地防止数据被收集。

这对我来说毫无意义。

  1. 问题不只是detached 仍然被脚本引用(因为它是一个闭包)detached = null 不应该足以让 GC 收集 detached 并消除泄漏吗?
  2. 如果 p 已被删除,为什么它仍然保留对 detached 的引用?如果 (1) 为真,则不应该

    p.appendChild(detached);
    p.removeChild(detached);
    

    什么都不做?

【问题讨论】:

    标签: javascript google-chrome dom memory-leaks profiling


    【解决方案1】:

    是的,这是写得很糟糕的文档。如果fill() 方法曾经引用过全局对象(例如fill2()),这句话就有意义,所以我怀疑示例代码在某些时候发生了变化。

    detached = null 将按照以下示例解决内存泄漏。

    function start()
    {
      var p = document.getElementsByTagName("div")[0];
      detached = document.createElement("div");
      p.appendChild(detached);
      p.removeChild(detached);
      fill();
    }
    
    function fix()
    {
      detached = null;
    }
    
    function fill()
    {
      for (var i = 0; i < 25; ++i) {
        var div = document.createElement('div');
        div.data = new Array(10000);
        for (var j = 0, l = div.data.length; j < l; ++j)
          div.data[j] = j.toString();
        detached.appendChild(div);
      }
    }
    
    function fill2()
    {
      window.data = new Array(10000);
      for (var j = 0, l = window.data.length; j < l; ++j)
        window.data[j] = j.toString();
    
      for (var i = 0; i < 25; ++i) {
        var div = document.createElement('div');
        div.data = window.data;
        detached.appendChild(div);
      }
    }
    

    【讨论】:

      最近更新 更多