我在Tomcat中遇到线程内存泄漏错误,我使用的是ThreadPool,但在我的webapp中没有ThreadLocal的实现 .
严重:Web应用程序[/ myWebApp]使用[org.a pache.http.impl.cookie.DateUtils $ DateFormatHolder $ 1]类型的键创建了一个ThreadLocal(值[org.apache.http.imp l.cookie.DateUtils $ DateFormatHolder $ 1 @ 4c2849])和类型为[java.lang.re f.SoftReference]的值(值[java.lang.ref.SoftReference@1e67280])但在Web应用程序停止时无法重新调用它 . 线程将会更新,以便尝试避免可能的内存泄漏 .
我不明白为什么我收到threadlocal错误,虽然我没有实现它?我想摆脱这些消息,所以我搜索了网络,并在here写道,为了清理我需要使用的threadlocal:
ThreadLocal.remove()
但我没有ThreadLocal的实现..如果有人给我指路,我将不胜感激 .
4 回答
显然,有些东西正在创建那些/那些ThreadLocal实例 . 如果它不是您的代码,那么它必须是您正在使用的某个库,或者(不太可能)Tomcat本身 .
我将从查看可能正在创建实例的内容开始
(顺便说一下,这是
DataUtils
中嵌套类中的匿名类...所以除非有些奇怪的东西,否则创建将在DateUtils.java
文件中出现 . )如果检查源代码没有帮助,请尝试调试Tomcat实例并在ThreadLocal构造函数上设置断点 .
问题出在您的第三方库中 . 您不能在线程池环境中使用线程本地,除非您在每个请求结束后真正清理它们 .
本文解释了这个问题:http://blog.maxant.co.uk/pebble/2008/09/23/1222200780000.html
ThreadLocal显然是由你使用的一些框架或库创建的(看看哪一个正在使用HttpClient),但正如你在日志中看到的那样,值是SoftReference,它应该最小化内存泄漏 .
事实上你可以在code中看到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及其类加载器,避免了我认为的大量泄漏:(