WebappClassLoader memory leak even without gc roots

HERE HEAD DUMP (UPDATED 10/29/2013)

I work in webapp with:

  • Tomcat 7.0.24
  • Java 6
  • Spring 3 (with aop-cglib)
  • SLF4J over Log4j
  • Oracle Coherence

After much work, I managed to remove all the strong link to the class loader, and now it is a candidate for the garbage collector. So, is the memory leak resolved? Of course not! Because after several hot deployments, OOME appears due to PermGen space.

Thanks to Yourkit, I was able to verify that WebappClassLoader was a pending completion, which means that it is waiting in the finalizer queue (in fact, this is not WebappClassLoader itself, but one of its referents). Checking the memory snapshot I found some Finalizer links for Oracle Coherence classes ... enter image description here

This sounds like an β€œokey”: Coherence objects are waiting for garbage collection, thanks to all the hard work that removes all strong links (killing all connectivity threads, removing Java security providers, etc.) I think there is nothing to do here.

So, I was thinking of doing finalize , which breaks something and then doesn't allow the empty finalizer queue. But it’s strange that with JMX or jmap -finalizerinfo finalizerinfo, the finalizer queue seems empty! All this is very confusing, so I continued to search elsewhere ...

What do you think here to do? I read something about CGLIB improving the finalize method . If I have access to the Enhancer , I can create a callback filter as described here , but I don't know how to manage this using Spring AOP.

Well, searching elsewhere, I found some weak links from java.lang.reflect.Proxy . Are these jdk dynamic proxies? Or are they related to Introspection memory leaks? with weak links?

enter image description here

INFO: I use a Spring context listener that clears introspector caches ( java.beans.Introspector.flushCaches() ). What else can I do with this?

Let's continue.

Then we have some other weak links from java.io.ObjectStreamClass$Caches . Many of my business objects have such weak links.

enter image description hereenter image description here

Maybe I need to flush these caches. But how?

Then we have these weak links related to com.sun.internal.ResourceManager , java.util.logging.Logging and java.lang.reflect.Proxy

enter image description here

What can I do with these weak links? Do I need to worry about this or is there a problem in the finalizer queue? Any clue will help ... really: -D

And, one more thing, I found a weak link from the "main" tomcat theme, which will never be updated by tomcat. I know that my application may leave some local var thread in some tomcat threads, but tomcat 7 update these threads to avoid memory leaks of the class loader . enter image description here

I think this is the weirdest thing in my memory snapshot, but is this a weak referee? What can I do about it?

EDIT: Reading java.lang.ref javadoc I found this:

An object is poorly accessible if it is neither strong nor mildly reachable, but can be achieved by passing a weak link. When weak references to a weakly reachable object are cleared, the object becomes suitable for completion.

So, can weak links store objects on the heap when they implement the finalize method?

Meanwhile, I found the answer to this question, I managed to remove all weak links to my classloader, but two: ClassLoaderLogManager.classLoaderLoggers and the one that is associated with the tomcat stream.

NOTE. Actually, I managed to delete the first one, but this link was again set by tomcat after / during deployment.

EDIT: SERVICE RESULTS

I tried plumbr and no reports on the web console. Only this message on standard output

 Dumping heap to /opt/tomcat7/headdumps/java_pid9478.hprof ... Heap dump file created [348373628 bytes in 3.984 secs] # # An unexpected error has been detected by Java Runtime Environment: # # Internal Error (javaCalls.cpp:40), pid=9478, tid=1117813056 # Error: guarantee(!thread->is_Compiler_thread(),"cannot make java calls from the compiler") # # Java VM: Java HotSpot(TM) 64-Bit Server VM (11.2-b01 mixed mode linux-amd64) [thread 1110444352 also had an error] # An error report file with more information is saved as: # [thread 1110444352 also had an error] # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # ****************************************************************************** * * * Plumbr has noticed that JVM has thrown an OutOfMemoryError: PermGen space. * * * * You can increase PermGen size with -XX:MaxPermSize parameter. * * If you encountered this error after a redeploy, please read next article: * * http://plumbr.eu/blog/what-is-a-permgen-leak * * * ****************************************************************************** 
+6
source share
1 answer

I think Yourkit has led you to the wrong path.

I looked at your dump heaps using the Eclipse Memory Analyzer. He showed that WebappClassLoader is referenced by the class com.inovasoftware.iap.data.access.platform.datarepository.CoherenceDataRepository $$ EnhancerByCGLIB $$ 180c0a4e, which is an instance in the local local stream variable. Some search engines have shown this: https://hibernate.atlassian.net/browse/HHH-2481

Perhaps updating the version of Hibernate will be useful.

MAT screenshot

+2
source

All Articles