be careful to free leak when changing innerHTML of an element
Douglas Crockford points out that if you assign a closure to the event handler of an element and then remove this element from the DOM tree, IE's garbage collector cannot deallocate memory properly and hence a memory leak occurs.
Well, it is not a recent issue. And I have mentioned it before both in here and in my codeproject article as well.
Though things may not be always obvious:
Let us say you have filled a div with fifty links using javascript/ajax. And when you click "next page" link, you change the innerHTML of the div and fill it with a brand new set of links.
Moreover, let us assume that after you set the innerHTML (well I'm not discussing whether innerHTML is good or evil, but it generally makes lazy peoples' life easier) you attach every single link in this div an onclick event handler like this:
That is, you define a closure for each link. Which generates a circular reference.
And then when you click the "next page" link and re-fill the innerHTML, those closures will no be reclaimed.
Welcome to our good old "circular reference causing memory leak in IE" story.
To sort this out you can break the circular chain one by one:
or use a custom sweeper function as Douglas offers:
Cheers.
bu yaziyi sevdin mi?
hemen
una ekle!
Well, it is not a recent issue. And I have mentioned it before both in here and in my codeproject article as well.
Though things may not be always obvious:
Let us say you have filled a div with fifty links using javascript/ajax. And when you click "next page" link, you change the innerHTML of the div and fill it with a brand new set of links.
Moreover, let us assume that after you set the innerHTML (well I'm not discussing whether innerHTML is good or evil, but it generally makes lazy peoples' life easier) you attach every single link in this div an onclick event handler like this:
for(i=0;i<len;i++)
{
links[i].onclick=function(){...dummy stuff...};
}
That is, you define a closure for each link. Which generates a circular reference.
And then when you click the "next page" link and re-fill the innerHTML, those closures will no be reclaimed.
Welcome to our good old "circular reference causing memory leak in IE" story.
To sort this out you can break the circular chain one by one:
function nextbtn_click(evt)
{
/*good boys clean up their mess first*/
for(i=0;i<len;i++)
{
links[i].onclick=null;
}
/*
*now we can set the innerHTML
*since there are no leaking elements around
*/
document.getElementById("targetLayer").innerHTML=
newSetOfLinksThatPopOutOfAnAJAXResponse;
}
or use a custom sweeper function as Douglas offers:
/*
* Code directly taken from Douglas' web site:
* http://www.crockford.com/javascript/memory/queuetest3.html
*/
function purge(d) {
var a = d.attributes, i, l, n;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
n = a[i].name;
if (typeof d[n] === 'function') {
d[n] = null;
}
}
}
a = d.childNodes;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
purge(d.childNodes[i]);
}
}
}
Cheers.
bu yaziyi sevdin mi?
hemen
una ekle!


