Send As SMS
Note: This blog is sorta marketing-related and less frequently updated than other blogs that I author. If you are more of a techy-geek than a marketing wizard then cre8ive hut will be much interesting for you.
Volkan.

10.24.2005

internet explorer memory leakage problem continued

This is a follow-up of my prior post on memory leakage.

IE's problem is not 100% related to circular references (using circular references just makes the issue more apparent) It has more to do with usage of closures.

There is more on MSDN to describe the ie leak patterns.

If you do not know what closures are, I recommend an excellent web page describing them. They are excellent pieces to use, but can be very harmful if you use them improperly. Nevertheless closures are a powerful construct. Better keep them in your inventory.

Let us begin with a sample non-leaking code (non-cross-browser)

[html]
[head]
[meta http-equiv="refresh" content="1;" /]
[script type="text/javascript"]
window.onload=function(evt){

var obj=document.getElementById("my-element");

obj.attachEvent("onclick",fn_handler);

/*in order to observe the leakage*/
obj.bigString=new Array(1000).join(new Array(200).join("XXXXX"));

};//onload

function fn_handler(evt){
alert("hello world!");
}
[/script]
[/head]
[body]
[div id="my-element"]cccc[/div]
[/body]
[/html]


no closure pattern

The assignment of obj.bigString will not affect anything because it will be deallocated as soon as window.onload function exits.

Now let us create a closure and see how things change:

[html]
[head]
[meta http-equiv="refresh" content="1;" /]
[script type="text/javascript"]
window.onload=function(evt){
var obj=document.getElementById("my-element");

obj.attachEvent("onclick",fn_handler);

/*the closure*/
var fn_handler=function(evt){
alert("hello world!");
};

/*in order to observe the leakage*/
obj.bigString=new Array(1000).join(new Array(200).join("XXXXX"));
};//onload
[/script]
[/head]
[body]
[div id="my-element"]cccc[/div]
[/body]
[/html]

closure pattern

Here the DOM node ("my-element") is referencing the closure (fn_handler) through its onclick attribute.

OTOH the obj variance that is within the scope of the closure (fn_handler) is referencing the DOM node ("my-element").

A la circular reference!

Since the JScript garbage collector is a mark and sweep GC, you may think that it should handle circular references. And in fact it does. However this circular refernce is between DOM and JS worlds and DOM and JS have separate garbage collectors. So they cannot cleanup memory in situations like this.

Microsoft admits IE's leak and says:

"Don't use closures unless you really need closure semantics. In most cases, non-nested functions are the right way to go"

I don't agree with them. If something is useful, but their impementation is buggy, why should I need to avoid using it. The bug has to be fixed not avoided.

So you have several choices at hand:

1. You don't care and pray that your application doesn't blow up.
2. Write your own garbage collection mechanism (not as difficult as it sounds)
3. Don't use closures.

So my humble advice is, use closures (they are extremely useful) but know the consequences of it and handle them accordingly.

One simple approach is to write a closure that unloads all the events, does does other necessary cleanup and unloads itself as a final step.

Comments: Yorum Gönder

<< Home

This page is powered by Blogger. Isn't yours?