Guice + Tomcat潜在的内存泄漏

我刚刚开始在我的Tomcat webapp中使用Google Guice,并且每当WAR文件取消部署时,都会在catalina.out文件中注意到以下内容:

May 16, 2011 5:37:24 PM org.apache.catalina.startup.HostConfig checkResources INFO: Undeploying context [/app] May 16, 2011 5:37:24 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: A web application appears to have started a thread named [com.google.inject.internal.util.$Finalizer] but has failed to stop it. This is very likely to create a memory leak. May 16, 2011 5:37:24 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap SEVERE: A web application created a ThreadLocal with key of type [null] (value [com.google.inject.internal.InjectorImpl$1@10ace8d]) and a value of type [java.lang.Object[]] (value [[Ljava.lang.Object;@7e9bed]) but failed to remove it when the web application was stopped. To prevent a memory leak, the ThreadLocal has been forcibly removed.

May 16, 2011 5:37:24 PM org.apache.catalina.startup.HostConfig checkResources INFO: Undeploying context [/app] May 16, 2011 5:37:24 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: A web application appears to have started a thread named [com.google.inject.internal.util.$Finalizer] but has failed to stop it. This is very likely to create a memory leak. May 16, 2011 5:37:24 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap SEVERE: A web application created a ThreadLocal with key of type [null] (value [com.google.inject.internal.InjectorImpl$1@10ace8d]) and a value of type [java.lang.Object[]] (value [[Ljava.lang.Object;@7e9bed]) but failed to remove it when the web application was stopped. To prevent a memory leak, the ThreadLocal has been forcibly removed.

May 16, 2011 5:37:24 PM org.apache.catalina.startup.HostConfig checkResources INFO: Undeploying context [/app] May 16, 2011 5:37:24 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: A web application appears to have started a thread named [com.google.inject.internal.util.$Finalizer] but has failed to stop it. This is very likely to create a memory leak. May 16, 2011 5:37:24 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap SEVERE: A web application created a ThreadLocal with key of type [null] (value [com.google.inject.internal.InjectorImpl$1@10ace8d]) and a value of type [java.lang.Object[]] (value [[Ljava.lang.Object;@7e9bed]) but failed to remove it when the web application was stopped. To prevent a memory leak, the ThreadLocal has been forcibly removed.

有谁知道是什么原因引起的,或者我怎么能阻止它发生?

我只按照此处的说明http://code.google.com/docreader/#p=google-guice&s=google-guice&t=ServletModule

……还没有做过什么花哨的事。 我只有2个servlet和一个filter。

谢谢!

如果你在关闭webapp时得到这个,我不会太担心。 这种类型的资源泄漏应用程序。 关机很常见。 当你经常进行热部署时(即在不杀死JVM的情况下多次部署),它们确实会成为一个问题,但是当冷部署完成时它们不会出现问题(在部署之前完成取消部署/部署重新部署)。

一种常见的策略是您在开发期间进行热部署(因为它们通常比冷部署更快),并且只在资源泄漏开始影响您的性能时才进行冷部署。 然后,在生产中,您将在每次部署时执行冷部署。 鉴于具有此类泄漏的代码/库的数量,尝试消除它们将是很难的IMO。

根据Guice问题630,它应该在下一个Guice版本(截至2011年11月)中修复,即当Guava 依赖关系升级到r10 +时。

根据Guice第288期 ,似乎修复仍未解决。

这有助于我摆脱com.google.inject.internal.InjectorImpl的“SEVERE”日志条目:

 injector = null; System.gc(); 

注入器是Guice.createInjector(...modules...)

我承认,看起来我没有读过关于调用System.gc()的坏习惯 ,但它完全有道理,因为Guice在内部使用弱引用。

PS Tomcat 8,Java 8,Guice 3.0