views:

98

answers:

3

I have an application that displays tables of data, in a paged format. Clicking on a "page" button re-renders the table. (These are not HTML pages - these are just buttons that re-populate my table with a new "page" of data) Each table cell has event handlers attached to it.

For all intents and purposes, if the application starts on "Page 1", I click "Page 2", and then I click "Page 1", the application's state SHOULD be identical to that of the starting condition.

So far, so good.

Unfortunately, I notice (In Chrome, Firefox, etc), that after clicking on different "pages", my app is leaking memory.

To try to find the cause of it, I've clicked on 20 "pages", and then set what should be the only global controller object I use to null.

That had very little effect on memory consumption.

I then tried to invoke

document.body.remove();

Sure enough, that removed the body element, leaving me with no HTML.

The app still consumes 20MB of memory (Chrome).

I'm at a loss. When I deleted my global controller object, there should be no more references to it. Since it's also the only place that contains references to my data, as well as all my functions, the memory should be freed.

When I take a heap snapshot, I see this:

Constructor - Reference Count - Size

Object  95570   17.69MB
Array   126652  6.14MB
(closure)   72457   5.57MB
klass   57959   1.55MB
String  47461   1.26MB
Arguments   34780   1.06MB
HTMLTableCellElement    15146   709.19KB
HTMLInputElement    14624   685.48KB
(code)  3042    616.88KB
HTMLElement 10459   490.25KB
Variety 2027    132.48KB
HTMLTableRowElement 1242    57.44KB
(anonymous) 11  47.64KB
(global property)   1557    12.16KB
HTMLTableSectionElement 80  2.19KB
HTMLTableElement    41  1.90KB
RegExp  29  1.70KB
HTMLDivElement  46  1.26KB
Console 2   460B
Error   19  456B
d   18  360B
subclass    8   224B
MathConstructor 3   156B

The overwhelming majority of those references are closures (I use a lot of them in my event handlers). How should I go about finding the memory leak?

A: 

Notice: you dont delete anything, you only remove something from the document-tree. The removed node(body) is still a DOM-Node(will for example be returned by Node->removeChild(), I guess that's what prototype uses in remove() )

I think there is no DOM-Method to delete a node.

Maybe you could try something else to free some memory, e.g. create a DOM-Range, select the Node(body) and delete the contents of the Range() .

Another "legal" method does'nt come to my mind this moment, use of innerHTML I would'nt suggest in this case.

Dr.Molle
After removing the body, document.childNodes reverts to returning the HTML of the starting page (Prior to the tables getting created and populated). Trying to use document.removeChild() on the body element didn't reduce my memory consumption either.
Vladislav
A: 

I couldn't identify the source of the leak - so my solution was to, instead of re-generating the table's DOM + Event handlers on every page click, I would change the values of the elements in the table, leaving the DOM untouched.

The moral of the story, seems to be that you should be very careful with code that generates DOM elements + Event handlers - and test it for leaks before it gets too complicated.

Vladislav
A: 

i use drip for detecting ie memory leak

jebberwocky