当我创建10,000个元素时,为什么内存使用量不会增长?

Cod*_*ert 5 html javascript frontend dom

当我创建10,000个元素时,内存使用量不会增长.但是当我引用这些10,000个元素时,内存使用量从3.5M增加到4.0M.当我破坏参考时使用量减少0.1M,而删除元素则减少0.4M.

这是我的问题:

  1. 当我创建10,000个元素时,为什么内存使用量不会增长?
  2. 当我引用这10,000个元素时,为什么内存使用会显着增长?
  3. 为什么在销毁引用时使用量只会略微减少而删除元素会明显减少?

操作系统:El Capitan 10.11.3 浏览器:Chrome 48.0.2564.116(64位)

创建元素后(3.5M内存使用)

创建元素后

制作参考(4.0M内存使用)后

在做参考之后

(function(){
  var elemArray = [];
  var elemCount = 10000;
  //create 10000 elements and append to the dom tree
  var create = function(){
    var i = 0;
    var zone = document.getElementById("zone");
    for(;i<=elemCount;i++){
      var div = document.createElement("div");
      div.id = "div" + i;
      div.innerHTML = "the " + i + " div";
      zone.appendChild(div);
    }
  };
  document.getElementById("create").addEventListener("click",create,false);

  var clear = function(){
    var zone = document.getElementById("zone");
    zone.innerHTML = "";
  };
  document.getElementById("clear").addEventListener("click",clear,false);

  var link = function(){
    var i = 0;
    for(;i<=elemCount;i++){
      elemArray[i] = document.getElementById("div" + i);
    }
  };
  document.getElementById("link").addEventListener("click",link,false);

  var unlink = function(){
    if(elemArray.length > 0)
      elemArray.splice(0,elemArray.length);
  }
  document.getElementById("unlink").addEventListener("click",unlink,false);
})();
Run Code Online (Sandbox Code Playgroud)
<button id="create" >create 10000 elements</button>
<button id="clear" >delete 10000 elements</button>
<button id="link" >reference 10000 elements</button>
<button id="unlink" >destroy reference</button>
<div id="zone"></div>
Run Code Online (Sandbox Code Playgroud)

Rob*_*rto 1

一切似乎都按预期进行。

OP 的代码将元素添加到使用 C++ 内存堆的 DOM。然后,当 Javascript 附加到这些元素时,将创建一个使用 Javascript 内存的包装对象。然后,该内存使用情况会显示在Chrome 内存分析器中。

有趣的是,如果您为每个新 div 添加名称属性,那么内存使用量会立即增加 0.5mb。仅添加一个 id(如 OP 的代码)不会产生该峰值(带有 div)。可以使用下面的代码片段和 Chrome 分析器对此进行测试。

这是之前的一个问题,可能可以更好地解释它:

具有 id 的 DOM 树元素会成为全局变量吗?

测试代码

var LIMIT = 10000,
  zone = document.getElementById('zone'),
  count = document.getElementById('count');


window.b1.onclick = function() {
  var i;
  for (i = 0; i < LIMIT; i++) {
    zone.appendChild(document.createElement('div'));
  }
  show();
}

window.b2.onclick = function() {
  var i, e;
  for (i = 0; i < LIMIT; i++) {
    e = document.createElement('div');
    e.id = 'id' + i;
    zone.appendChild(e);
  }
  show();
}

window.b3.onclick = function() {
  var i, e;
  for (i = 0; i < LIMIT; i++) {
    e = document.createElement('div');
    e.name = 'na' + i;
    zone.appendChild(e);
  }
  show();
}

window.b4.onclick = function() {
  var i, e;
  for (i = 0; i < LIMIT; i++) {
    e = document.createElement('div');
    e.id = 'id' + i;
    e.name = 'na' + i;
    zone.appendChild(e);
  }
  show();
}

window.b5.onclick = function() {
  zone.innerHTML = '';
  show();
}

function show( ) {
  var e = zone.getElementsByTagName('div');
  count.innerHTML = 'total elements = ' + (e ? e.length: '0');
}
Run Code Online (Sandbox Code Playgroud)
button {
  width: 8em;
}
Run Code Online (Sandbox Code Playgroud)
<div>Memory Test: <span id="count"></span></div>

<button id="b1">none</button>
<button id="b2">with id</button>
<button id="b3">with name</button>
<button id="b4">with name + id</button>
<button id="b5">clear</button>

<div id="zone"></div>
Run Code Online (Sandbox Code Playgroud)