我在Tomcat 7中有一个Web应用程序。
当我关闭Tomcat时,我看到了这些警告(但并非总是如此)
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.
关闭时catalina.out中这些警告意味着什么? 我看到我提到的一些JAXB类,但不知道这里有什么问题。
请帮忙吗?
答案 0 :(得分:24)
简而言之,某些ThreadLocals尚未正确清理。大多数(如果不是全部)J2EE服务器/应用程序容器使用线程池来处理传入请求和其他任务,以防止始终开始新线程的开销。问题是某些库(以及你自己,如果你不知道更好)在任务/请求执行结束后不清理他们的ThreadLocals。
通常,当线程在执行结束时死亡时,不再引用存储在ThreadLocals中的对象,垃圾收集器负责删除这些对象:
每个线程都拥有对其本地线程副本的隐式引用 只要线程是活动的并且是ThreadLocal实例的变量 可以访问;一个线程消失后,它的所有副本 线程局部实例受垃圾回收(除非其他 存在对这些副本的引用。)
但是当从线程池中获取线程时,它不会死掉,而是返回到池中。由于线程仍处于活动状态,因此引用的ThreadLocals也是如此。当使用相同的ThreadLocal并且之前使用过处理请求/任务的线程时,这表现为内存泄漏和从一个请求到另一个请求的“泄漏”。
答案 1 :(得分:13)
您的应用程序中有一个或多个内存泄漏。有关这些问题发生的完整解释,哪些是您的错,以及您可以采取哪些措施来修复它们,请参阅此演示文稿: http://people.apache.org/~markt/presentations/2010-11-04-Memory-Leaks-60mins.pdf
答案 2 :(得分:10)
至少有一条JAXB消息似乎与已知错误有关:
org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks严重:Web应用程序 [/ MyApplication]使用类型的键创建了一个ThreadLocal [com.sun.xml.bind.v2.ClassFactory $ 1](价值 [com.sun.xml.bind.v2.ClassFactory$1@25442544])和类型的值 [java.util.WeakHashMap中]
请参阅JAXB-563和JAXB-831(注意 - 这些是在java.net上,需要登录才能查看)。第一个错误被认为是固定的,但正如其他人所评论的那样,并没有完全修复。第二个错误有一个建议的解决方法,即在让上下文关闭之前强制执行gc()可以缓解问题(虽然不能完全消除它) - 您可以使用自定义ServletContextListener
并简单地调用{{1}在System.gc()
方法中。
至于其他错误,您需要遵循其他答案建议并进行一些严肃的调试。