我在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的实现..如果有人给我指路,我将不胜感激。
答案 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及其类加载器,避免了我认为的大量泄漏:(