Memory Leaks, createElement, and Form Controls.



I've just closed all windows in Firefox and its using 244MB of memory.

I have no idea why. I had GMail open, a page from unicode, the CLJ FAQ.

I've noticed that createElement leaks. It's obvious with form controls because the form keeps the control name as a property.

Example:

<!doctype html>
<body>
<form><input name="foo"/></form>

<script>
document.forms[0].foo;
document.forms[0].innerHTML = "";
document.write(document.forms[0].foo);
</script>
</body>

Will output:
[object HTMLInputElement]

(or similar implementation-dependent string).

If a node is added to the document, memory is allocated for that node.
When that node is removed, the memory usage goes back down, but not to
where it was before.

So FORM controls leak memory. This came up here:
http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/db8447c9ef6b0710?tvc=1

So what happens if I create, say 100 divs, then remove them?

Using Firefox 3.0.1
Well, I did that. I restarted Firefox. and noted the memory usage at "53mb".

I filled in "100" for the text input and clicked "periodicCreate()".

It reached 100 after a less than a minute. I checked the memory usage again and it was 89.38mb.

I clicked "destroy" and waited a few minutes, watching the memory increase and Firefox became unresponsive and CPU spiked to 100%.

"destroy" completed several minutes later, and I noted the memory usage at 85.00mb.

A minute later, real memory remains at around 85mb. I reloaded the page. 85mb. I navigated to google.com. Still at 85mb.

Here is my test page:

<!DOCTYPE html>
<html lang="en">
<head>
<title>div Memory Leak</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<style type="text/css">
input { display: none; }
</style>
</head>
<body>
<h1>Adding DIV to DIV</h1>
<button onclick="create()">create()</button>
<button onclick="destroy()">destroy()</button>
<button onclick="periodicCreate()">periodicCreate()</button>
<input type="text" value="20" style="display:block" id='per'>
<pre id="mon">
Check memory consumption before starting.
</pre>
<pre id="mon2">
-
</pre>
<div id='cont'><!-- if the form element tag is changed to "div",
the leak does not occur --></div>
<script type='text/javascript'>
var mon = document.getElementById('mon'),
keyMon = document.getElementById('mon2').firstChild;
var p = document.getElementById('cont');
keys = [];
function create() {
var n = "n" + +new Date;
keys.push(n);
setTimeout(addInputs, 10);
}

function addInputs() {
var inp = document.createElement('div'),
c,
n = keys[keys.length-1];
for(var i = 0; i < 1000; i++) {
c = inp.cloneNode(false);
// add a title property,
// to increase memory.
c.title = "T" + i;
p.appendChild(c);
}
keyMon.data += (keys.length) + " name prefix: " + n + " please wait.\r\n";
addInputs.done();
}
addInputs.done = function(){};

function periodicCreate() {
if(periodicCreate.i == +document.getElementById('per').value)
return;
create();
addInputs.done = function() {
periodicCreate.i++;
periodicCreate();
};
}
periodicCreate.i = 0;

function destroy() {
mon.innerHTML = "setting innerHTML = ''. Please wait...";
p.innerHTML = "";
mon.innerHTML = "done. Check memory consumption again.";
}
</script>

</body>
</html>
===========================================

So, Firefox leaks memory with createElement/appendChild.
.