在多个帖子中都提到:不当使用ThreadLocal
导致内存泄漏。我正在努力理解内存泄漏是如何发生的ThreadLocal
.
我想到的唯一场景如下:
Web 服务器维护一个线程池(例如,用于 servlet)。如果变量在这些线程中,则可能会造成内存泄漏ThreadLocal
不会被删除,因为线程不会消亡。
这个场景没有提到“Perm Space”内存泄漏。这是内存泄漏的唯一(主要)用例吗?
永久代耗尽结合ThreadLocal
往往是由类加载器泄漏.
一个例子:
想象一个应用程序服务器有一个池工作线程.
它们将保持活动状态,直到应用程序服务器终止。
部署的 Web 应用程序使用static ThreadLocal
在它的一个类中为了存储一些线程本地数据,另一个类的实例(我们称它为SomeClass
)的网络应用程序。这是在工作线程内完成的(例如,此操作源自HTTP请求).
重要的:
根据定义,对一个的引用ThreadLocal
value一直保留到“拥有”线程死亡或者 ThreadLocal 本身不再可达。
如果网络应用程序无法清除引用 to the ThreadLocal
关机时,会发生不好的事情:
因为工作线程通常永远不会消亡,并且对ThreadLocal
是静态的,则ThreadLocal
value 仍然参考的实例SomeClass
,一个 Web 应用程序的类 -即使网络应用程序已停止!
因此,Web 应用程序的类加载器无法被垃圾回收, 意思就是所有课程Web 应用程序(以及所有静态数据)保持加载状态(这会影响 PermGen 内存池以及堆)。
Web 应用程序的每次重新部署迭代都会增加 permgen(和堆)的使用量。
=> 这是永久元泄漏
这种泄漏的一个常见例子是this bug在 log4j 中(同时修复)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)