4

我在 Tomcat 中遇到线程本地内存泄漏错误,我正在使用 ThreadPool,但在我的 web 应用程序中没有实现 ThreadLocal。

严重:Web 应用程序 [/myWebApp] 创建了一个 ThreadLocal,其键类型为 [org.a pache.http.impl.cookie.DateUtils$DateFormatHolder$1](值 [org.apache.http.imp l.cookie.DateUtils$DateFormatHolder $1@4c2849])和类型为 [java.lang.ref.SoftReference] 的值(值 [java.lang.ref.SoftReference@1e67280]),但在 Web 应用程序停止时未能将其删除。线程将随着时间的推移而更新,以尝试避免可能的内存泄漏。

我不明白为什么我没有实现线程本地错误?我想摆脱这些消息,所以我搜索了网络,在这里写到为了清理我需要使用的线程本地:

ThreadLocal.remove()

但我没有 ThreadLocal 的实现。如果有人告诉我一个方法,我将不胜感激。

4

4 回答 4

2

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

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

于 2012-05-02T14:14:22.837 回答
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 及其类加载器,避免了我相信的大部分泄漏:(

于 2014-06-26T10:04:34.827 回答
2

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

我将首先查看可能创建的实例

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

(顺便说一句,这是嵌套类中的匿名类DataUtils......所以除非发生奇怪的事情,否则DateUtils.java文件中将发生创建。)

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

于 2012-05-02T14:21:31.950 回答
2

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

事实上,您可以在 DateUtils 的代码中看到它正在创建 Threadlocal...

于 2012-05-02T14:23:42.430 回答