Threadpool中的Threadlocal内存泄漏

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

严重:Web应用程序[/ myWebApp]创建了一个ThreadLocal,其键类型为[org.a 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])但在Web应用程序停止时无法重新调用它。 线程将会更新并且有时间尝试避免可能的内存泄漏。

我不明白为什么我得到线程局部错误,虽然我没有实现它? 我想摆脱这些消息,所以我搜索了网络,并在这里写道,为了清理threadlocal我需要使用:

ThreadLocal.remove() 

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

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

我将从查看可能正在创建实例的内容开始

  org.apache.http.impl.cookie.DateUtils$DateFormatHolder$1 

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

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

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

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

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

实际上你可以在DateUtils的代码中看到它正在创建Threadlocal ……

这是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及其类加载器,避免了我认为的大量泄漏:(