I ran into an "interesting" issue with sqlmaps today.

I've been trying to get a webapp into a state where it can be reloaded
repeatedly without eventually failing but this turns out to be almost
impossible (see http://www.szegedi.org/articles/memleak.html for an
entertaining write up). The JDK has various places that can hold references
to classes loaded by a webapp classloader, which prevents the webapp
classloader from being garbage collected (see
http://www.docjar.com/docs/api/sun/net/www/http/HttpClient.html and
http://www.docjar.com/html/api/sun/net/www/http/KeepAliveCache.java.html for
examples). Eventually the (Sun) JVM runs out of PermGen space, throws an
OutOfMemoryError and all is lost.

Tomcat 5.5 tries to clean up various things in the clearReferences method of
its WebappClassLoader, like deregistering jdbc drivers, clearing various
IntrospectionUtils caches, releasing the commons logging LogFactory, etc.
but there are so many different things that hold references it is fighting a
losing battle.

In trying to rearrange various jars in the app I'm working with to avoid
holding references from outside the webapp classloader to classes inside the
webapp classloader I noticed that sqlmaps has similar issues. The ClassInfo
CLASS_INFO_MAP holds onto a static map keyed by class. If the sqlmap jars
are loaded from outside the webapp classloader (in Tomcat's common or shared
libs) this map can hold references to classes loaded by the webapp
classloader. These references keep the webapp classloader live in the eye of
the garbage collector and it will never be reclaimed. This keeps all the
classes loaded by the webapp classloader live and eats up PermGen space
fairly quickly.

Here's another good link that notes problems with sqlmaps as well
http://www.java-community.de/archives/140-Memory-leaks-et-alii.html

There are so many other places that do similar things that fixing sqlmaps
probably won't help the situation much, but it sure can't hurt. It would be
nice if sqlmaps could be changed to use weak references to the cached
reflection information so that it isn't the reason a webapp classloader
can't be reclaimed by the garbage collector.

Cheers,
Derek

Reply via email to