Threadpool中的Threadlocal内存泄漏

时间:2012-05-02 13:49:30

标签: java tomcat thread-local threadpool

我在Tomcat中遇到threadlocal内存泄漏错误,我正在使用ThreadPool,但在我的webapp中没有ThreadLocal的实现。

  

SEVERE:Web应用程序[/ myWebApp]使用[org.a]类型的键创建了一个ThreadLocal   pache.http.impl.cookie.DateUtils $ DateFormatHolder $ 1](value [org.apache.http.imp   l.cookie.DateUtils$DateFormatHolder$1@4c2849])和类型为[java.lang.re]的值   f.SoftReference](值[java.lang.ref.SoftReference@1e67280])但没有rem   当Web应用程序停止时,请将其关闭。线程将被更新为ove   是时候尝试避免可能的内存泄漏。

我不明白为什么我收到threadlocal错误,虽然我没有实现它?我想摆脱这些消息,所以我在网上搜索,并在here中写道,为了清理我需要使用的threadlocal:

ThreadLocal.remove()

但我没有ThreadLocal的实现..如果有人给我指路,我将不胜感激。

4 个答案:

答案 0 :(得分:2)

问题在于您的第三方库。您不能在线程池环境中使用线程本地,除非您在每个请求结束后真正清理它们。

本文解释了这个问题: http://blog.maxant.co.uk/pebble/2008/09/23/1222200780000.html

答案 1 :(得分:2)

显然,某些东西正在创建那些/那些ThreadLocal实例。如果它不是你的代码,那么它必须是你正在使用的某个库,或者(不太可能)Tomcat本身。

我首先看看可能会创建

的实例
    org.apache.http.impl.cookie.DateUtils$DateFormatHolder$1

(顺便说一句,这是DataUtils中嵌套类中的匿名类......所以除非有些奇怪的东西在上,否则创建将在DateUtils.java文件中出现。)

如果检查源代码没有帮助,请尝试调试Tomcat实例并在ThreadLocal构造函数上设置断点。

答案 2 :(得分:2)

ThreadLocal显然是由您使用的某个框架或库创建的(看看哪一个正在使用HttpClient),但正如您在日志中看到的那样,值是SoftReference,它应该最小化内存泄漏。

事实上你可以在code中看到DateUtils正在创建Threadlocal ...

答案 3 :(得分:2)

这是HttpClient JIRA:https://issues.apache.org/jira/browse/HTTPCLIENT-1216

从版本4.2.2开始,有一个clearThreadLocal()方法,从4.3开始,不推荐使用cookie-DateUtils,并将其替换为org.apache.http.client.utils.DateUtils。

在关闭时调用DateUtils.clearThreadLocal()一次是不够的,它只清除当前线程的ThreadLocal,因此您需要在执行在该线程上解析/格式化日期的HTTP请求后调用它。这消除了使用ThreadLocal的大部分性能优势。

或者,如果从您控制下的线程(不是由Tomcat创建)执行HTTP请求,请记住在应用程序关闭时关闭所有线程池/执行程序。

很遗憾HttpClient很容易被修改为不覆盖ThreadLocal,然后ThreadLocal不会引用webapp及其类加载器,避免了我认为的大量泄漏:(