了解 Chrome 和 'Uncovering DOM leaks' 示例中的内存泄漏

Understanding memory leaks in Chrome and the 'Uncovering DOM leaks' example

在 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
}

然后他们声称这是泄漏,因为

..a DOM node is detached from the tree, but it still holds DOM wrapper objects that reference script data, effectively preventing the data from being collected.

这对我来说毫无意义。

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

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

    什么都不做?

是的,文档写得很糟糕。如果 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);
  }
}