18

I have a web application in Tomcat 7.
When I shut down Tomcat I see these warning (but not always)

SEVERE: The web application [/MyApplication] created a ThreadLocal
with key of type
[org.apache.xml.security.algorithms.MessageDigestAlgorithm$1] (value
[org.apache.xml.security.algorithms.MessageDigestAlgorithm$1@2e2c2e2c])
and a value of type [java.util.HashMap] (value
[{http://www.w3.org/2000/09/xmldsig#sha1=MESSAGE DIGEST SHA-1}]) 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.
Apr 3, 2012 1:56:19 PM org.apache.catalina.loader.WebappClassLoader
checkThreadLocalMapForLeaks   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@25442544]) and a value of type
[java.util.WeakHashMap] (value [{class
com.classes.internal.ContactType=java.lang.ref.WeakReference@17eb17eb,
class
javax.xml.bind.annotation.adapters.HexBinaryAdapter=java.lang.ref.WeakReference@178a178a,
class
com.classes.internal.xjc.ListType=java.lang.ref.WeakReference@181c181c,
class
com.classes.internal.xjc.MessageType=java.lang.ref.WeakReference@17711771,
class
com.classes.internal.xjc.MessageType=java.lang.ref.WeakReference@17011701}])
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.   Apr 3, 2012 1:56:19 PM
org.apache.catalina.loader.WebappClassLoader
checkThreadLocalMapForLeaks   SEVERE: The web application
[/MyApplication] created a ThreadLocal with key of type
[org.apache.xml.security.utils.UnsyncBufferedOutputStream$1] (value
[org.apache.xml.security.utils.UnsyncBufferedOutputStream$1@4a904a90])
and a value of type [byte[]] (value [[B@67486748]) 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.  

What do these warnings mean in catalina.out on shutdown?
I see some of my JAXB classes mentioned, but can't tell what the issue is here.

Any help please?

sixtyfootersdude
  • 25,859
  • 43
  • 145
  • 213
Jim
  • 18,826
  • 34
  • 135
  • 254

3 Answers3

24

In a nutshell, some ThreadLocals have not been cleaned properly. Most (if not all) J2EE-servers / Application Containers use thread pools for incoming requests and other tasks, to prevent the overhead of starting new threads all the time. The problem is that some libraries (and you yourself, if you don't know better) don't clean up their ThreadLocals after the execution of the task/request ends.

Normally, as the thread dies on end of execution, the objects stored in ThreadLocals are no longer referenced and the garbage collector takes care of removing such objects:

Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local instances are subject to garbage collection (unless other references to these copies exist).

But when the thread has been fetched from a thread pool, it does not die, but instead is returned to the pool. Since the thread is still alive, so are the referenced ThreadLocals. This manifests both as memory leaks and "leaking" of values from one request to another when the same ThreadLocal is used and the thread handling the request/task was used before.

esaj
  • 15,875
  • 5
  • 38
  • 52
  • 1
    +1.I don't use thread locals in my code.How can I look more into this? – Jim Apr 06 '12 at 10:03
  • 1
    @Jim See here for monitoring: http://tomcat.apache.org/tomcat-7.0-doc/monitoring.html , after enabling the JMX-remote, you can use for example JConsole (comes with JDK) to access it. The ThreadLocals are probably from some library you're using. As a wild guess, as these warnings do not always appear, it's possible that some library was doing something when you shutdown the application, so Tomcat *could* be giving false positives. If the memory usage of the application does'nt keep growing over time when in use for longer periods and you don't redeploy often, I wouldn't worry about it so much. – esaj Apr 06 '12 at 12:40
17

You have one or more memory leaks in your application. For a full explanation of why these occur, which ones are your fault and what you can do to fix them see this presentation: http://people.apache.org/~markt/presentations/2010-11-04-Memory-Leaks-60mins.pdf

Mark Thomas
  • 16,339
  • 1
  • 39
  • 60
10

At least one of the JAXB messages appears to relate to a known bug:

org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks 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@25442544]) and a value of type [java.util.WeakHashMap]

See JAXB-563 and JAXB-831 (NB - These are on java.net and require a login to even view). The first bug was supposedly fixed but as others have commented this is not fully fixed. The second bug has a suggested workaround which is to force a gc() before letting the context shutdown which does mitigate the problem (though not eliminate it entirely) - you can use a custom ServletContextListener and simply call System.gc() in the contextDestroyed() method.

As for the other errors you need to follow the other answers advice and do some serious debugging.

RobV
  • 28,022
  • 11
  • 77
  • 119
  • Man, this seems to be my problem, but I can't start the application in Tomcat because it keeps giving me this error. I already changed the web.xml with the new ServletContextListener. Any suggestions? – Christian Vielma May 08 '13 at 21:20
  • 2
    I hit this problem when running Jersey on Tomcat, with the Datastax Cassandra drivers. Even though I closed the Cassandra cluster connection in contextDestroyed() I was still getting the thread / memory leak errors every time I redeployed the app. Adding System.gc() after the cluster.close() took care of the problem. – m.kocikowski May 14 '14 at 23:44