As Stephen C mentioned, the memory leak is indeed because of classloaders. But the problem is more acute than at first glance. Consider this:
mapkey --> class --> classloader --> all other classes defined by this classloader.
Furthermore,
class --> any static members, including static Maps e.g. caches.
A few such static caches can start adding up to serious amounts of memory lost whenever a webapp or some other dynamically (classloaded) loaded app is cycled.
There are several approaches to working around this problem. If you don't care about different 'versions' of the same class from different classloaders, then simply key based on Class.getName()
, which is a java.lang.String
.
Another option is to use java.util.WeakHashMap
. This form of Map only maintains weak references to the keys. Weak references don't hold up GC, so they key won't cause a memory accumulation. However, the values are not referenced weakly. So if the values are for example instances of the classes used as keys, the WeakHashMap
does not work.