How can I find the memory leak in my Javascript?
I have an application that displ开发者_Go百科ays 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?
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.
i use drip for detecting ie memory leak
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.
精彩评论