Weblogic 服务器不自动清理 ThreadLocal 对象导致内存泄漏问题的解决方案

最近更新于 2018-11-13。

适用于

Oracle Weblogic 服务器 - 版本 10.3.5 及以后。
本文信息适用于任何平台。

问题

在一个线程执行结束以后,Weblogic 服务器并不会清理设置在 ThreadLocal 里的对象。这会导致内存泄漏。
使用 Eclipse 内存分析工具 MAT (Memory Analysis Tool) 跟踪的一个内存泄漏的例子:

  1. 右击内存泄漏的可疑对象 -> Path To GC -> With All Reference
    Right click on the suspicious leaking object.jpg
  2. 该对象由 Weblogic 执行线程 ‘19’ 的 ThreadLocal 对象所引用
    The object is referred by the ThreadLocal object of ExecuteThread.jpg
  3. 执行线程 ‘19’ 当前没有侍服于任何请求,它是 idle 的
    ExecuteThread is not working on any request.jpg

解决方案

请参考 Java API 文档:http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html

每一个线程会一直对其 ThreadLocal 变量的副本保留一个隐式的引用,只要该线程还是 alive 状态的且该 ThreadLocal 实例还是可访问的;一旦线程消亡,其下所有 ThreadLocal 的拷贝都会划入垃圾回收的范畴 (除非还有其他对这些拷贝的引用)。

Weblogic 自带一个线程池管理机制。分配给一个线程的一个任务完成以后,该线程并不会被销毁。相反,该线程会被归还给线程池。因此,存储于 ThreadLocal 中的对象并不会被自动清理。
对此,我们已经提交了一个增强请求:尚未发布的缺陷 15975482:AUTOMATICALLY CLEAN OUT THREAD LOCAL TO AVOID MEMORY LEAK。
自动清理功能计划在 WLS 12.2.1 或以后的版本中实现。对于当前已发布的版本,请务必在程序中确认存放在 ThreadLocal 中的对象在线程归还给线程池之前已被手工清理掉。
原文链接:WebLogic Server Does Not Clean the Objects in ThreadLocal Automatically (Doc ID 1929223.1)

猜你喜欢

转载自blog.csdn.net/defonds/article/details/85615215