Beware The Unused Thread
By Adrian Sutton
Many people think that because Java has garbage collection, that memory leaks aren’t possible – this is totally and utterly wrong. One really good way to introduce leaks into Java programs without blatantly holding on to object references is to create a new thread and then not use it. Once you create a thread, it is added to the list of runnable threads. I’m not sure why, but even before the thread is actually started, Java treats it as a running thread and holds on to it. Obviously threads that are currently running shouldn’t be garbage collected, but it seems like an unfortunate side effect that newly created threads also can’t be garbage collected. Once you know about it, the solution is simple – only ever create a thread immediately before you call its start method.
Today however, I learnt another unusual way to introduce memory leaks – start a javax.swing.Timer instance and don’t keep a reference to it. The person who originally wrote this piece of code obviously thought that the Timer defaulted to firing once. It doesn’t. Timer’s default to spawning a new thread and continuing to fire the action until you call its stop method. This wouldn’t be so bad if it weren’t for the fact that the ActionListener passed to the timer was an internal class and thus brought along references to the rest of the system.
On the plus side, out of this ordeal I’ve managed to set up a simple way to profile our applet rather than just profiling the bean. The codebases only differ by one or two classes, but this memory leak was one that only appeared in the applet (and then only in a specific situation). I probably should document the pain I went through to get it working at some point, but not tonight.