Reputation: 4673
The following javascript code seems to leak memory but I’m not sure why. I’ve tried this in chrome 19 and firefox 12. The code is below:
<body>
<input id="add" type="button" value="add" onclick="add()" />
<input id="remove" type="button" value="remove" onclick="remove()" />
<div id="content">
</div>
</body>
<script>
var count = 0;
function add() {
var i = 0,
newdiv;
for (i = 0; i < 10000; i++) {
newdiv = document.createElement('div');
document.getElementById("content").appendChild(newdiv);
newdiv.setAttribute('id', "div" + count);
newdiv.innerHTML = "section " + count;
newdiv = null;
count = count + 1;
}
}
function remove() {
var i = 0;
for (i = 0; i < count; i++) {
document.getElementById("content").removeChild(document.getElementById("div" + i));
}
count = 0;
}
</script>
When you keep clicking the add button and then the remove button the memory in Windows Task Manager keeps increasing. I expected the memory to decrease at some point when garbage collection kicks in but this never seems to happen.
So, my questions are: is there a memory leak in this code? And if so how can I refactor the code to fix the leak?
Upvotes: 3
Views: 2497
Reputation: 3932
I can not really prove there is a memory leak... but just imagine you want to clean up 10000 bottles after a good sports game, takes some time and resources ;)
besides some mabye helpful comments: use a closure to encapsule that code from the window object. use a local reference to document to avoid scope chain walkthrough, usa a fragment to append all the new divs and not access document every time, avoid function overhead (these all are just suggestions and not necessarily THE thing you are looking for but good ones anyway and should at least reduce the problem a little bit :)
NOTE: these examples might not all work completely cross browser
<body>
<input id="add" type="button" value="add">
<input id="remove" type="button" value="remove">
<div id="content"></div>
</body>
<script>
(function(DOC) {
var count = 0, getById = DOC.getElementById, createFragment = DOC.createDocumentFragment;
getById("add").addEventListener("click", function() {
var i = 0,
newdiv,
fragment = createFragment();
for (; i < 10000; i++) {
newdiv = document.createElement('div');
newdiv.id = "div" + count;
newdiv.innerHTML = "section " + count;
fragment.appendChild(newdiv);
delete newdiv;
}
getById("content").appendChild(fragment);
count = i;
}, false);
getById("remove").addEventListener("click", function() {
var element, i = 0;
for (; i < count; i++) {
element = getById("div" + i);
element.parentNode.removeChild(element);
}
count = 0;
}, false);
})(document);
</script>
I hope this helps in either solving or at least reducing the leak. =)
Upvotes: 0
Reputation: 1198
I have tested this with Chrome 19.0 and yes, you are right, memory increases. But after about 30 Seconds, garbage collection kicks in and it gets back to normal.
Upvotes: 2