13

I'm investigating a memory leak in a Tomcat/Spring/Hibernate app which is causing the dreaded "out of permgen" error after a few redployments. I've downloaded the free version of plumbr, which confirms that I have a classloader leak, but unfortunately I can't afford the $499 to get the detailed report. Is there a free tool that can perform an equivalent analysis and tell me where to look for it? Or some other common cause of such leaks that I can investigate?

Steps I've taken so far:

  • Ensure my JDBC driver is unregistered at context shutdown
  • Manually shut down the MySQL driver's AbandonedConnectionCleanupThread (per Tomcat Guice/JDBC Memory Leak)

What else might be causing the leak?

Community
  • 1
  • 1
Jules
  • 14,841
  • 9
  • 83
  • 130
  • 4
    As a partial answer to my own question, there's a comprehensive list of common causes of classloader leaks here: http://java.jiderhamn.se/2012/02/26/classloader-leaks-v-common-mistakes-and-known-offenders/ – Jules Feb 23 '14 at 09:40
  • Which version of Tomcat do yo use? Tomcat 7.+ does have some support for memleak detection – fge Feb 23 '14 at 10:24
  • I'm on tomcat 7, and have already fixed all the leaks it can detect, but there's still leaking happening somewhere else. – Jules Feb 23 '14 at 13:04

2 Answers2

5

You can use the evaluation version of JProfiler to investigate the class loader leak. Go to the class loader probe, select one of the leaking class loaders and show them in the heap walker where you can investigate strong references to the classes that were loaded by the class loader.

There is a screen cast that shows you how to do this.

Disclaimer: My company develops JProfiler.

Ingo Kegel
  • 46,523
  • 10
  • 71
  • 102
  • Thanks. It looks like a useful tool, but I found another way before I saw this response. – Jules Feb 24 '14 at 18:20
5

I found that Eclipse's Memory Analysis Tools worked reasonably well. I set my server to produce a heap dump and used MAT (roughly following the guide here) to find all the classloaders. It seems the relevant one is org.apache.catalina.loader.WebappClassLoader, and by listing their GC roots I was easily able to find out that my problem was being caused by java.util.logging.Level which was indirectly referenced through an org.jboss.logging.JDKLevel.

Now I just need to figure out how to prevent JBoss Logging doing this...

Jules
  • 14,841
  • 9
  • 83
  • 130
  • The answer to which is to make sure that one of the logging targets it supports is present in the classpath. I chose log4j, which just needed dropping into my WEB-INF/lib directory. – Jules Feb 24 '14 at 21:34