I just had an interview, and I was asked to create a memory leak with Java. Needless to say I felt pretty dumb having no clue on how to even start creating one.
What would an example be?
Answer:
Here’s a good way to create a true memory leak (objects inaccessible by running code but still stored in memory) in pure Java:
- The application creates a long-running thread (or use a thread pool to leak even faster).
- The thread loads a class via an (optionally custom) ClassLoader.
- The class allocates a large chunk of memory (e.g.
new byte[1000000]
), stores a strong reference to it in a static field, and then stores a reference to itself in a ThreadLocal. Allocating the extra memory is optional (leaking the Class instance is enough), but it will make the leak work that much faster. - The thread clears all references to the custom class or the ClassLoader it was loaded from.
- Repeat.
This works because the ThreadLocal keeps a reference to the object, which keeps a reference to its Class, which in turn keeps a reference to its ClassLoader. The ClassLoader, in turn, keeps a reference to all the Classes it has loaded. It gets worse because in many JVM implementations Classes and ClassLoaders are allocated straight into permgen and are never GC’d at all.
A variation on this pattern is why application containers (like Tomcat) can leak memory like a sieve if you frequently redeploy applications that happen to use ThreadLocals in any way. (Since the application container uses Threads as described, and each time you redeploy the application a new ClassLoader is used.)
Update: Since lots of people keep asking for it, here’s some example code that shows this behavior in action.