Fixing Leaks
From Drip IE Leak Detector
| Revision as of 23:41, 12 June 2006 Matthiasmiller (Talk | contribs) (→Pseudo-Leaks) ← Previous diff |
Current revision Jrosman (Talk | contribs) (→Pseudo-Leaks) |
||
| Line 76: | Line 76: | ||
| } | } | ||
| - | // detach element | + | // move the element to the garbage bin |
| - | if (element.parentNode) | + | |
| - | element = element.parentNode.removeChild(element); | + | |
| - | + | ||
| - | // discard element | + | |
| garbageBin.appendChild(element); | garbageBin.appendChild(element); | ||
| garbageBin.innerHTML = ''; | garbageBin.innerHTML = ''; | ||
| }</pre></blockquote> | }</pre></blockquote> | ||
Current revision
Contents |
Fixing Leaks
There are two common causes of memory leaks.
Closures
This code will cause a memory leak:
function loadMyPage() {
var elem = document.getElementById('myelement');
elem.onclick = function () {
window.alert('hi!');
};
}
To solve this, you could add:
elem = null;
Or, you could refactor the code somewhat:
function onMyElemClick() {
window.alert('hi!');
}
function loadMyPage() {
var elem = document.getElementById('myelement');
elem.onclick = onMyElemClick;
}
Expandos and Circular References
This code contains a circular reference and will cause a memory leak:
function Helper(elem)
{
this.elem = elem;
}
var elem = document.getElementById('elem');
elem.helper = new Helper(elem);
Circular references with other elements will also leak. For example:
var parent = document.getElementById('parent');
var child = document.getElementById('child');
// make it easy to find one from the other
parent.other = child;
child.other = parent;
To resolve these leaks, you must ensure that the elements do not cross-reference each other, either directly or indirectly.
Pseudo-Leaks
Sometimes Internet Explorer keeps items in memory after the page is done using them. Although these pseudo-leaks are freed after the user leaves the page, some web pages may be open for long periods of time.
To avoid pseudo-leaks, do not use removeChild to remove elements. Instead, set the parent's innerHTML to "" or use a function like this:
function discardElement(element) {
var garbageBin = document.getElementById('IELeakGarbageBin');
if (!garbageBin) {
garbageBin = document.createElement('DIV');
garbageBin.id = 'IELeakGarbageBin';
garbageBin.style.display = 'none';
document.body.appendChild(garbageBin);
}
// move the element to the garbage bin
garbageBin.appendChild(element);
garbageBin.innerHTML = '';
}
