Wednesday 31 July 2013

JavaScript - Memory Leak Diagnostics

Memory leaks in JavaScript seem to be becoming an ever increasing problem. This is no surprise with JavaScript being used more and more but have you ever tried to solve a memory leak in JavaScript? It's no simple task, the tools simply don't exist to help determine what objects are leaking. You're essentially trying to find a needle in a haystack while blindfolded. Not Cool!

Until now.

There are three tools I would like to talk about. Sieve, Google Chrome's Heap Snapshot and the new boy on the block, Internet Explorer 11 Developer Tools.

In most cases, as a developer, you need a bit of a nudge in the right direction. Once you have an idea of where the problem may lie, we're pretty intelligent, we can usually work it out. Sieve gives you that nudge.
It's a memory leak detector for Internet Explorer. When running it'll show you all the DOM elements that are currently in memory. It'll then go one step further and it'll show you the DOM nodes that are currently leaking with an ID and everything. You can then use that information to try and find out why it's leaking. Usually it's because some piece of JavaScript some where references the element which has since been removed from the DOM.
sIEve - Memory Leak Detector

I must admit, I used this on a complex web application which had popup windows with iframes inside iframes and if it didn't crash then it did report some nodes were leaks when they weren't but, it did at least give me that nudge to look at a particular screen.

Chrome Heap Snapshot
Now we're talking! This is, to my knowledge, is the first proper way of determining what objects are specifically leaking. It allows you to take a snapshot of what objects are in memory at a given point in time and then you can compare these snapshots.

Chrome Heap Snapshot
This is rather handy. It means you can see which objects were created in the first snapshot and still exist in the second snapshot, i.e. the ones that are causing your problem!

The good thing about these snapshots is that it also tells you the "retaining tree". This is essentially the path from the root objects to the object in question, this means you can trace the path and work out why your object isn't being garbage collected.

The tool has a few other ways of helping you find your leak if comparing snapshots isn't quite cutting it. There is a "containment" view and a "dominator" view. I haven't had much use for the containment view (see here for more details) but the dominator view essentially lists the objects with the biggest memory consumption which can be helpful if you've got leaking global objects.

And a late entry.... Internet Explorer 11 Heap Snapshot
A developers preview has just been released on Windows 7 but so far so good. It's much the same as Chrome's version, if a little easier to read.

Internet Explorer 11 Developer Tools
There are two exceptions, firstly, on a positive note, it has a search functionality which Chrome doesn't have. This allows you to find objects that you know the id of. On a negative, it seems you can only compare sequential snapshots. You could not for example, compare your first and third snapshot which means you have to really think about when to take a snapshot.

I haven't had much time to really play around with this and it is only a developers preview but so far it looks like it could be a very useful tool. In actual fact, the whole new developer tools has a real potential but that's another blog post for another day.

For more info on the memory tab within the developer tools check out the MSDN documentation.

Conclusion...
As always, use the best tool for the job. For simple leaks, sieve is very good in finding the problem. For more complex problems the heap snapshots are the way to go.

The work Google and Microsoft have done in this area recently show how big JavaScript has now become and these tools are a great addition to any web developers tool kit.

If you do ever have to look for a memory leak, my thoughts are with you.

Good luck!