在多个帖子中都提到了这一点:不当使用ThreadLocal会导致内存泄漏。我正在努力了解使用内存泄漏将如何发生ThreadLocal。
ThreadLocal
我发现的唯一情况如下:
Web服务器维护一个线程池(例如,用于servlet)。如果ThreadLocal未删除其中的变量,则这些线程可能会导致内存泄漏,因为线程不会死亡。
这种情况下没有提到“ Perm Space”内存泄漏。那是内存泄漏的唯一(主要)用例吗?
PermGen的exhaustions 与组合ThreadLocal往往是由引起 的类加载器泄漏 。
一个示例: 想象一个具有 工作线程 池的应用服务器。 它们将保持活动状态,直到应用程序服务器终止。 部署的Web应用程序在其一个类中使用一个 静态 ThreadLocal变量来存储一些线程本地数据,该数据SomeClass是Web应用程序的另一个类的实例(以下简称它)。这是在工作线程中完成的(例如,此操作源自 HTTP请求 )。
SomeClass
重要提示: 根据定义,对 值 的引用ThreadLocal __保留直到“拥有”线程死亡或ThreadLocal自身不再可访问。
如果Web应用程序 无法清除参考 到ThreadLocal 上关机 ,不好的事情会发生: 由于工作线程通常不会死和参考ThreadLocal是静态的,该ThreadLocal值 仍然引用 的情况下SomeClass,Web应用程序的类- 即使Web应用程序已停止!
因此, 无法 对Web应用程序的 类加载器进行垃圾回收 ,这意味着Web应用程序的 所有类 (和所有静态数据)都将 保持加载状态。 (这会影响PermGen内存池以及堆)。 Web应用程序的每次重新部署迭代都会增加permgen(和堆)的使用。
= >这是permgen泄漏这种泄漏的
一个流行示例是 log4j中的此bug(同时已修复)。