首页 文章

Threadpool中的Threadlocal内存泄漏

提问于
浏览
4

我在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 回答

  • 2

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

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

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

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

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

  • 2

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

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

  • 2

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

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

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

相关问题