PDA

View Full Version : IE Memory Leak Experiences, Need Help with Analysis



JEBriggs
7 Jun 2010, 7:59 AM
I'm curious to know what experiences people are having with memory leaks in IE. We are in the process of migrating a very large JavaScript application from 2.30 to 3.21 and have discovered a number of large memory leaks (in IE) that suddenly appeared when we switched codebases. These memory leaks occur when the page is refreshed.

It appears as the potential memory leaks were present in our code, but never surfaced when we were using ExtJs 2.3.0. (I'm testing in IE 7).

I'd like to know what kinds of leak problems other are experiencing, but I have a couple specific questions:


Is my analysis of our code (see below) correct
If so, what was introduced in ExtJs 303 onwards that would account for the "activating" of the memory leak.


Let me summarize the issue. We create an list of items (UL of LIs). Each LI has an assigned id and we attach two listeners to each LI--by calling addClassOnHover and by calling addListener. We use a XTemplate to write the list into the DOM. Then, by accident, we do it again. We create a second set of LIs with the same IDS, attach listeners and overwrite the first set of LIs.

(This was never a problem with 2.30)

Here's our code which contains a memory leak:


MyComponent=Ext.extend(Ext.Component,{

//This tpl gets overwritten twice
tpl: new Ext.XTemplate(
'<tpl for=".">',
'<li id="{id}"><a onclick="return false">{text}</a></li>',
'</tpl>'),



PopulateHeaderMenu gets called TWICE in MyComponent.onRender and this is the source of the problem

populateHeaderMenu: function(){

//Create a new array[7] and populate it with and element id and handler.

this.headerMenu = [];

this.headerMenu.push({
id: "m-header-x-tab", text: "xxxx",
handler: function(){
this.activatexxxTools();
Ext.ux.m.common.addHistory(this.xconfig);
}
});

/*
What is the effect of overwriting the dom with elements with the same sets of ids?
Could this cause a leak?
*/
this.tpl.overwrite(this.el, this.headerMenu);


// bad coding, but not the cause of the leak
for (var i=0; i<this.headerMenu.length; i++) {
Ext.each(this.headerMenu, this.attachMenuHandler, this);
}

}//end populateHeaderMenu

/*
Gets called twice. Instead of creeating 7 sets of hover and click listeners,
we create 14. The first set is not used because the elements that they are attached to
are overwritten. The 7 overwritten elements have listeners attached. Do they ever get cleaned up?
*/
attachMenuHandler: function(menu,index) {
if (!menu.el) {
menu.el = $(menu.id);
menu.el.addClassOnOver('hover');
if (menu.handler) {
menu.el.on("click", menu.handler, menu.scope || this, {"menu": menu});
}
}
},


Why doesn't the EventManager remove both sets of listeners? Is this because the Ext.elCache is a "map" by id and when the second set of listeners is added into the elCache--by id--, the original entry into the cache is overwritten? Consequently, the events are not cleaned up on the EventManager unload event?


EventManager in Ext-foundation.js

function addListener(el, ename, fn, task, wrap, scope){
el = Ext.getDom(el);
var id = getId(el),
es = Ext.elCache[id].events,
wfn;
...

};

function getId(el){
...
if(!Ext.elCache[id]){
Ext.Element.addToCache(new Ext.Element(el), id);
if(skip){
Ext.elCache[id].skipGC = true;
}
}
}





Finally, given the above, is there a way to globally address this issue so that we can make our application more robust? Its likely that we have more leaks and I'd like to be able to fix the problem globally without having to identify each leak.

Sgt.Pepper
8 Jun 2010, 1:50 AM
Without giving it much thought, my first idea would be to make proper use of event propagation.
Instead of attaching a listener to each and every <li>, you could attach just one listener to the <ul>. Thus you would only need 1 listener instead of 7.

Also, it is always a good idea to keep track of the handlers and unassign them with un() when you dispose an element. Or bulk delete them with removeAllListeners().
You could also use the mon() instead of on() in Extjs 3.X. See this for more information: http://blog.extjs.eu/know-how/what-the-hell-is-mon-and-mun/

http://www.extjs.com/blog/2009/08/10/ext-js-30-be-outstanding/
See the section "Memory Management Improvements"

Sgt.Pepper
8 Jun 2010, 1:51 AM
And well, my best advise: Don't support IE at all :)