2012-04-03 109 views
13

我在Tomcat的7
Web应用程序时我关闭Tomcat我看到这些警告(但不总是)catalina.out中的这些警告是什么?

SEVERE: The web application [/MyApplication] created a ThreadLocal 
with key of type 
[org.apache.xml.security.algorithms.MessageDigestAlgorithm$1] (value 
[[email protected]2e2c]) 
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 
[[email protected]]) and a value of type 
[java.util.WeakHashMap] (value [{class 
[email protected]b17eb, 
class 
javax.xml.bind.a[email protected]178a178a, 
class 
[email protected]1c181c, 
class 
c[email protected]17711771, 
class 
c[email protected]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 
[[email protected]a90]) 
and a value of type [byte[]] (value [[[email protected]]) 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类,但不能说出问题在这里。

请帮忙吗?

回答

23

简而言之,一些ThreadLocals没有得到妥善清理。大多数(如果不是全部的话)J2EE服务器/应用程序容器为传入请求和其他任务使用线程池,以防止始终开始新线程的开销。问题是某些库(如果你不知道更好的话,你自己)在执行任务/请求结束后不清理它们的ThreadLocals。

通常,如在线程上执行的端模具,存储在ThreadLocals的对象不再引用和垃圾收集器需要除去这种对象的护理:

每个线程保持其拷贝的隐​​式引用只要线程处于活动状态并且可以访问ThreadLocal实例 ,就可以使用线程局部变量 ;线程消失后,线程本地实例的所有副本都将受到垃圾回收(除非存在对这些副本的其他 引用)。

但是,当线程从线程池中取出时,它不会死亡,而是返回到池中。由于线程仍然活着,所以引用的ThreadLocals也是如此。当使用相同的ThreadLocal并且之前使用处理请求/任务的线程时,这表现为内存泄漏和从一个请求到另一个请求的“泄漏”值。

+0

+ 1.我的代码中没有使用线程本地代码。我可以更多地了解它吗? – Jim 2012-04-06 10:03:06

+1

@Jim请参阅这里进行监控:http://tomcat.apache.org/tomcat-7.0-doc/monitoring.html,启用JMX远程后,您可以使用例如JConsole(随JDK提供)来访问它。 ThreadLocals可能来自您正在使用的某个库。作为一个疯狂的猜测,因为这些警告并不总是出现,所以当你关闭应用程序时,某些库可能会做某些事情,所以Tomcat *可能会给出误报。如果应用程序的内存使用量在长时间使用后不会持续增长,并且您不经常重新部署,我不会为此担心。 – esaj 2012-04-06 12:40:01

10

至少JAXB消息之一似乎涉及一种已知的错误:

org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks重度:Web应用程序 [/所有MyApplication]建立一个ThreadLocal与键入 [com.sun.xml.bind.v2.ClassFactory $ 1](值为 [[email protected]])和值为 [java.util.WeakHashMap ]

请参阅JAXB-563JAXB-831(注 - 这些在java.net上,需要登录才能查看)。第一个bug被认为是固定的,但是正如其他人所评论的那样,这并没有完全解决。第二个bug有一个建议的解决方法,在让上下文关闭之前强制执行gc(),这可以缓解问题(尽管不会完全消除该问题) - 您可以使用自定义ServletContextListener,并简单地在contextDestroyed()方法中调用System.gc()

至于其他错误,你需要遵循其他答案的建议,并做一些严重的调试。

+0

男人,这似乎是我的问题,但我不能在Tomcat中启动应用程序,因为它不断给我这个错误。我已经使用新的ServletContextListener更改了web.xml。有什么建议么? – 2013-05-08 21:20:51

+2

当我在Tomcat上运行Jersey并使用Datastax Cassandra驱动程序时,我遇到了这个问题。尽管我在contextDestroyed()中关闭了Cassandra集群连接,但我每次重新部署应用程序时仍然收到线程/内存泄漏错误。在cluster.close()处理完问题后,添加System.gc()。 – 2014-05-14 23:44:34