PDA

View Full Version : Javascript Memory Profiling


rtikku
06-22-2009, 02:22 PM
Hi all,

I mostly program in java and have a good understanding of what causes memory leaks, and how to write code so that it does not leak memory. Plus, there is a lot of information out there on this subject.

However, when it comes to javascript, my knowledge on memory leaks is flaky. When I run my application for a long amount of time without restarting the browser, i see the browser memory grow continuously, and it does not come down. That leads me to believe that my js has memory leaks.

The natural thought that comes to mind is to use a profiler and see where the memory is being spent. Firebug comes with a profiler but that does only CPU and not memory (pls correct me if i am wrong here).


How are you guys dealing with this issue? Can anyone offer some Ext coding guidelines/tips that we should keep in mind to prevent memory leaks in our application.

tia.

Rakesh

sabiola
07-08-2009, 10:19 AM
Hello,

I found this thread and I'm also very interested in profiling my application...
Perhaps somebody has some tips on this.

Greetings,
Stefan

Adam.Molnar
07-09-2009, 12:39 PM
All I know of is IE Drip:

http://outofhanwell.com/ieleak/index.php?title=Main_Page

tjstuart
07-09-2009, 09:42 PM
sIEve http://home.wanadoo.nl/jsrosman/ is you best bet. I had exactly the same problems as you describe with long-running applications and browser memory consumption. Ext does a decent job of cleaning itself up but there are some things it misses. I spent *days* with sIEve looking for rogue elements and then cleaning them up manually. In the end I achieved satisfactory results. One of the biggest mistakes is to use 'new ...' in configurations (better to use lazy instantiation).

There are some useful threads lurking around on this matter ... http://extjs.com/forum/showthread.php?t=55148

mjlecomte
07-09-2009, 11:37 PM
any background to why lazy initialization helps?

tjstuart
07-10-2009, 12:22 AM
any background to why lazy initialization helps?

As I performed this task many moons ago, the details are a little sketchy. What I recall is the following:-

Ext 2.2.1

We have a dynamic long-running app with (amongst many other things) a central region (panel) for displaying screens (also panels). These screens can contain any number of custom fields, grids, toolbars etc. All of these custom widgets extend Ext components in some way or another. Within the configs for these screens we originally had something like: tbar: new Our.custom.Toolbar(...). These toolbars contained buttons which in turn had event handlers etc. What we found was that the elements attached to these handlers were never being destroyed along with the screen (sIEve never reported them as "freed"). As the contents of these screens changes so too does the requirement of the toolbar, thus the need to destroy and re-create along with the screen itself.

Fast-forward a few days and ...

after passing raw toolbar configs to the 'tbar' config option (instead of using Toolbar constructor) the rogue nodes were reported as "freed" and to my delight, the leaks were gone.

As the problem was resolved I decided to move on to other things rather than find out what was actually causing the problem. At the time I don't think it made much sense to me as either method does essentially the same thing. Still with so much else to do I moved onward :)

I'm sure I've missed something else that I did but that is the "gist" of it.

sabiola
07-15-2009, 04:15 AM
Hello,

somebody know a tool for Firefox?
Because I'm on Linux or Mac...

Thanks,
Stefan

sabiola
07-15-2009, 04:17 AM
Hello,

One of the biggest mistakes is to use 'new ...' in configurations (better to use lazy instantiation).


we use this "new ..." in a lot of our configurations. Perhaps you can give here some code examples about "lazy instantiation"...

Thanks,
Stefan

Condor
07-15-2009, 04:50 AM
Using lazy instantiation doesn't solve memory leaks. It only reduces memory usage for components that have not yet been created.

Example of lazy instantiation:
var win = new Ext.Window({
title: 'Hello World',
width: 300, height: 200,
layout: 'form',
items: [new Ext.form.TextField({
fieldLabel: 'Text'
})],
buttons: [new Ext.Button({
text: 'OK'
}]
});
vs.
var winCfg = {
xtype: 'window',
title: 'Hello World',
width: 300, height: 200,
layout: 'form',
items: [{
xtype: 'textfield',
fieldLabel: 'Text'
})],
buttons: [{
xtype: 'button',
text: 'OK'
}]
});
And when the window needs to be shown you use:
var win = Ext.ComponentMgr.create(winCfg);

But back to memory leaks:
- What really causes memory leaks is registering listeners on elements and not removing them. You can catch these errors with sIEve.
- Another example is removing a component by only removing the DOM (e.g. by setting the innerHTML to '' instead of properly destroy()-ing a component). This is why you should (almost never) use render or renderTo! Try to use Ext containers as much as possible.
- I also don't recommend using the id (or storeId) config option of a store, because you often forget to unregister it from the StoreMgr after the store is no longer used. A JsonStore also has an id config option, which you should change to idProperty!

mabello
07-15-2009, 04:52 AM
Lazy initialization in the Ext Component life-cycle context means that you can use a config object with the xtype property instead of creating a new component explicitly with the new keyword.
So the creation of the component (and its rendering) is deferred until it actually has to be visualized and rendered into the browser.
Ext takes care of the actual creation of the right component type based on the xtype of the cfg object.

var p = new Ext.Panel //Explicit creation
{
...
items:[{//Lazy initialization using a cfg object
xtype: 'panel',
...
}]
}


Hope this helps

EDIT: Condor you are fast!