7

I have been chasing this for a few days now. We use JAXB, sun implementation, in our app. When stopping Tomcat (6 or 7) there is a severe memory leak logged in the catalina log file listing all the JAXB classes that we have in our application, two sets in two different packages.

I have been through a lot of google and Stack overflow links. I have used JProfiler which shows me that Tomcat is holding onto Enums when they are not used but this should not be the issue. All instances of marshaller or unmarshaller are created locally and set to null for aggressive GC. I ensure that JAXBcontext is null when servlets are destroyed and also in my contextDestroyed I run a System.gc(); as has been suggested to avoid the error.

But still the error is logged. I have seen in a Tomcat presentation that this is known error because a JarURLConnection lock is created by JAXBContext.newInstance() apparently this can be avoided by disabling caching, but this did nothing for me. http://people.apache.org/~markt/presentations/2010-11-04-Memory-Leaks-60mins.pdf

Any other suggestions as to how to fix this memory leak in JAXB running on Tomcat.

This is the error log:

SEVERE: The web application [/myApplication] created a ThreadLocal with key of type [com.sun.xml.bind.v2.ClassFactory$1] (value [com.sun.xml.bind.v2.ClassFactory$1@6a724da1]) and a value of type [java.util.WeakHashMap] (value [{class my.package.model.layout.Element=java.lang.ref.WeakReference@7646bb9f, class my.package.model.layout.ScriptBeforeFileID=java.lang.ref.WeakReference@1dc80063, class my.package.model.layout.OutputProperty=java.lang.ref.WeakReference@359172db, class my.package.model.layout.Data=java.lang.ref.WeakReference@600ba356, class my.package.model.layout.InputProperty=java.lang.ref.WeakReference@1c10945d, class my.package.model.layout.ToPort=java.lang.ref.WeakReference@47c7410, class my.package.model.layout.ConfigFile=java.lang.ref.WeakReference@6a7c8bd, class my.package.model.layout.LayoutInstanceID=java.lang.ref.WeakReference@716bf3b4, class my.package.model.layout.ScriptAfterFunction=java.lang.ref.WeakReference@664ce898, class be.securit.trustbuilder.config.model.........}]) 
    but failed to remove it when the web application was stopped. 
Threads are going to be renewed over time to try and avoid a probable memory leak.
        17-sep-2013 15:21:45 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks 
Gurnard
  • 1,773
  • 22
  • 43

2 Answers2

11

After going back through all the different posts I noticed mention of placing JAXB lib into the shared lib of Tomcat. So I removed the jaxb-impl-x.x.x.jar from my applications WEB-INF/lib and placed it into [TomcatHome]/lib. Now it all works lovely. Not sure this is the best though because now there needs to be a different method when installing under Tomcat.

Gurnard
  • 1,773
  • 22
  • 43
  • Didn't work for me. Can't see how moving jar will ork as they still get loaded in same way... – Neil Walker Jun 11 '15 at 22:51
  • 1
    Hello. If the jar is resident in the application scope and the application is re-deployed the jar is loaded each time the application is deployed he previous load of the classes are not removed as they hold a weak reference. If the jar is in the shared lib this does not happen. This instance is really only when in a development environment when you might re-deploy applications many times. – Gurnard Jun 12 '15 at 08:35
  • Moving jar to system Tomcat path doesn't fix bug in `jaxb-impl`. **Buggy library still forget to clean up thread local variables**. Tomcat checking code warns only if object reference to web application classloader, if `jaxb-impl` in `$CATALINA_HOME/lib` reference leads to system class loader. – gavenkoa Dec 19 '15 at 16:14
4

I had very similar problem. The leak was in jaxb context method realization:

StringWriter writer = new StringWriter(200);
JAXBContext context = JAXBContext.newInstance(objectClass);
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(object, writer);

this code creates new instance on every web-service request.

see this Memory leak in webservices with JAXB

shcherbak
  • 738
  • 8
  • 14