Thursday, April 1, 2010

Memory leaks? Yes indeed!

Phase I: Memory leak? No way!
I wasn't convinced when the testers said our Flex app has leaks. I thought it has to do with their machine's configuration or browser or whatever. Even when people came and said, they can see the app leaking in the Flex profiler i wasn't convinced, because i thought the profiler would be lying. In the past i rarely saw our apps leaking so i really thought it is false alarm. Also the randomness of the garbage collector helped to keep me in this mood of false safety.

Phase II: Memory leak? Indeed!
Since the potential bug had a huge impact on the success of the project and we were in the stabilization phase of the project, i had to find out, if it was real.
So what i did to convince myself, was to isolate a small part of the app and create a test app from it. And boom, the leak was clear to see in the instance counts of the profiler.

Phase III: Memory leak? The hunt is on.
First you need to find a set of steps, which clearly demonstrates the leak in the profiler. Ideally you automate this, because during your hunt you will execute these steps again and again.

Then you need to find the leak. Finding out about a memory leak in code, which otherwise looks perfectly good, needs a special mindset. You need to be suspicious about everything really. For me the best way to find it, is to reduce the search space by commenting as much as possible code out, until the leak doesn't show any longer. Then you go backwards by commenting pieces back in, until you see the leak. You can use a approach similar to binary search. You start with commenting in bigger parts until the leak shows, then you split this part and comment out smaller parts until it is gone and so on. Eventually you will find the leak hiding under a place you would never expect it ;)

Phase IV: Memory leaks? The candidates.
So now you have a suspicious line of code. To make 100% sure it is causing a leak, you create a small test project now, which demonstrates the leak in isolation.

Phase V: Memory leaks? The fix.
Now that you know what is causing the leak, you can go through your codebase and fix all the places which contains the suspicious code. If you are lucky, the leak is fixed now. Most of the time there will be no change at all though, because there are other leaks left. So you need to iterate this process and start again with Phase III.

It is a daunting process. I found it useful to pair with a colleague, so when you find something, your colleague can try to reproduce and confirm your theory. Eventually all the leaks are fixed and your app is ready to shine! Puh.

So much for the general process. More specifically we found leaks in our usage of BindingUtils. You need to make sure, that unwatch is called. Also some listeners needed to be removed or to be changed to weak listeners. We found that the SetEventHandler tag in a mxml state was leaking. And last but not least the Degrafa library was leaking, which is used for skins.

Halali (the german death-haloo),