首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ThreadLocal与内存泄漏

ThreadLocal与内存泄漏
EN

Stack Overflow用户
提问于 2013-07-31 11:14:42
回答 6查看 48.2K关注 0票数 62

在多个帖子中都提到了这一点:不适当地使用ThreadLocal会导致内存泄漏。我很难理解使用ThreadLocal是如何发生内存泄漏的。

我想出的唯一方案如下:

web服务器维护一个线程池(例如,对于servlet)。如果ThreadLocal中的变量没有被删除,因为线程不会死,那么这些线程就会产生内存泄漏。

这个场景没有提到"Perm“内存泄漏。这是内存泄漏的唯一(主要)用例吗?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-07-31 15:59:44

PermGen穷竭性ThreadLocal的结合常常是由类加载器泄漏引起的。

举个例子:

假设一个应用程序服务器有一个工作线程池。

它们将一直保持到应用服务器终止为止。

部署的web应用程序在其一个类中使用静态 ThreadLocal来存储某些线程本地数据,这是web应用程序的另一个类(让我们称之为SomeClass)的一个实例。这是在工作线程中完成的(例如,此操作来自HTTP请求)。

重要:

按定义,对ThreadLocal值的引用一直保持到“拥有”线程死亡,或者如果ThreadLocal本身不再可访问。

如果web应用程序未能清除关闭上的ThreadLocal 的引用,那么就会发生坏的事情:

因为工作线程通常不会死,而且对ThreadLocal的引用是静态的,所以ThreadLocal仍然引用SomeClass的实例-- web应用程序的类-,即使web应用程序已经停止!!

因此,web应用程序的类加载器不能被垃圾收集,这意味着 web应用程序的所有类(和所有静态数据)仍然加载(这会影响PermGen内存池和堆)。

web应用程序的每次重新部署迭代都会增加permgen (和堆)的使用。

=>这是permgen检漏

这种泄漏的一个流行例子是这只虫子 in log4j (同时修复)。

票数 89
EN

Stack Overflow用户

发布于 2013-07-31 12:04:33

线程局部变量本身没有什么问题:它们不会导致内存泄漏。他们不是很慢。它们比它们的非线程本地对应方更本地(也就是说,它们具有更好的信息隐藏属性)。当然,它们可能会被滥用,但大多数其他编程工具…也会被滥用。

请参阅约书亚·布洛赫的这个链接

票数 3
EN

Stack Overflow用户

发布于 2014-04-25 18:01:06

前面的文章解释了这个问题,但没有提供任何解决方案。我发现没有办法“清除”一个ThreadLocal。在处理请求的容器环境中,我最终在每个请求的末尾调用了.remove()。我意识到使用容器管理的事务可能会有问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17968803

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档