在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包装器对象,从而有效地防止了数据的收集。


这对我来说毫无意义。


问题不仅仅在于detached仍被脚本引用(因为它是一个闭包)吗? detached = null是否足以让GC收集detached并消除泄漏?
如果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);
  }
}

08-17 18:36