Although embarrassed to admit it, we have had long standing problems
with PermGen memory leaks. We have gotten used to restarting the server
every time we redeploy, to avoid OutOfMemoryError. Since we would like
to make use of - or at least evaluate - some of the new Resin features
like WAR versioning, I thought I’d give fixing this another shot.
I have already been through (and fixed a few of) the usual suspects;
JDBC drivers, log factories, ThreadLocals, explicit ClassLoader
references etc. There has also been at least one bug within Resin
causing leaks (bug 951 in Mantis).
A while back I tried tracking this down using jhat, but since I have
limited experience with this, time did not allow me to get to the bottom
of it. Today I found some more time, and also a tip on how to use
YourKit to track this down
for those interested). This lead me to something interesting, which I
don’t quite understand.
If I interpret the YourKit memory snapshot correctly, here is what is
happening (from a Resin 3.1.6 perspective):
In com.caucho.server.dispatch.ServletInvocation there is a static
ThreadLocal holding references to the current (original) request (while
dispatching?). This means that as long as the executing (and
dispatching) thread remains in Resins thread pool, but is not used for
another dispatch, a handle to the original
com.caucho.server.http.HttpRequest is held. In the request, there is a
handle to a com.caucho.server.dispatch.Invocation, which in turn has a
handle to - the application classloader! (And there is your PermGen leak)
Isn’t the fact that the ThreadLocal is never cleared an obvious memory
leak? Or why haven’t this been fixed even though Scott seems to have
noticed this (see
If the leak actually is in Resin, why isn’t anybody else seeing this???
Are we doing something unusual? (The only thing I could think of was
ServletRequest implementations inside the application being dispatched,
however I can't find any such implementations in use)
resin-interest mailing list