window.onload = function() {
var i = 0;
add.addEventListener("click", function() {
var d = document.createElement("div");
d.textContent = "Node";
d.addEventListener("click", function() {
alert(i++);
});
nodes.appendChild(d);
});
remove.addEventListener("click", function() {
nodes.removeChild(nodes.firstChild);
});
};
Even though the click handler on the div is refererring the variable i
in the closure, this is not going to create memory leaks. This is a feature
of the mark and sweep
garbage collection technique.
On the other hand, the following js will create memory leaks:
window.onload = function() {
var i = 0;
var arr = [];
add.addEventListener("click", function() {
var d = document.createElement("div");
d.textContent = "Node";
d.addEventListener("click", function() {
alert(i++);
});
nodes.appendChild(d);
arr.push(d);
});
remove.addEventListener("click", function() {
nodes.removeChild(nodes.firstChild);
});
};
We are keeping reference of the created div in the variable arr. So even
if they get removed from the DOM, the reference in the arr will prevent it
from garbage collected. One way to fix the problem is to remove the reference
from the array when we remove the element from DOM as well. The remove click
handler should be modified like this:
remove.addEventListener("click", function() {
var index = arr.indexOf(nodes.firstChild);
delete arr[index];
nodes.removeChild(nodes.firstChild);
});
Memory leaking pattern in JS
The following js code will not leak memory.
Even though the
click
handler on thediv
is refererring the variablei
in the closure, this is not going to create memory leaks. This is a feature of the mark and sweep garbage collection technique.On the other hand, the following js will create memory leaks:
We are keeping reference of the created
div
in the variablearr
. So even if they get removed from the DOM, the reference in thearr
will prevent it from garbage collected. One way to fix the problem is to remove the reference from the array when we remove the element from DOM as well. Theremove
click handler should be modified like this: