Thursday, June 6, 2013

Where's the memory leak?

A few days ago, I was tracking down a memory leak through Yourkit and I was pointed to this code (vastly oversimplified, but just complex enough to prove my point):

This code is part of a compiler and stores some metadata on an Abstract Syntax Tree node during byte-code creation. The profiler told me that there were thousands of ClosureWriter instances being kept around for the length of the compile (roughly one for each closure defined in the program). While not a huge amount of memory, this bothered me. For a while, I couldn't figure out why these references stuck around. Then it occurred to me that each reference to ClosureWriter.UseExistingReference.class keeps a back pointer to the enclosing ClosureWriter instance. By changing the UseExistingReference to static, the leak disappeared.

What's the lesson?

In Java, always, always declare your inner classes as static unless you are sure that you need back references to the enclosing instance.