Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the memory usage not grow when I create 10,000 elements?

The memory usage doesn't grow when I create 10,000 elements. But when I make references to these 10,000 elements, the memory usage grows from 3.5M to 4.0M. And the usage decreases by 0.1M when I destroy the reference while deleting the elements makes it decrease by 0.4M.

Here are my questions:

  1. Why doesn't memory usage grow when I create 10,000 elements?
  2. Why does memory usage grow significantly when I make references to these 10,000 elements?
  3. Why the usage decreases only slightly when references are destroyed while deleting the elements decreases it obviously?

OS: El Capitan 10.11.3 Browser: Chrome 48.0.2564.116 (64-bit)

After creating elements (3.5M memory usage)

after creating elements

After making references (4.0M memory usage)

after making references

(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);
})();
<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>
like image 240
doouding Avatar asked Nov 09 '22 19:11

doouding


1 Answers

Everything appears to be working as expected.

OP's code adds elements to the DOM which uses the C++ memory heap. Then when Javascript attaches to those elements a wrapper object is created which uses Javascript memory. And that memory usage then shows up in the Chrome memory profiler.

Interestingly, if you add a name attribute to each new div then there is an immediate 0.5mb spike of memory use. Just adding an id alone (like OP's code) does not produce that spike (with a div). This can be tested using the code snippet below and the Chrome profiler.

Here's a previous SO question that might explain it better:

Do DOM tree elements with ids become global variables?

Test Code

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');
}
button {
  width: 8em;
}
<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>
like image 180
Roberto Avatar answered Nov 14 '22 22:11

Roberto