由于未清除的 ThreadLocal 变量导致的内存泄漏

主要观点:在 Java 中常用静态、实例(成员)和局部变量,偶尔使用 ThreadLocal 变量,其对特定线程可见,常用于 Log4J 和 Hibernate 等框架,不用后不清除会导致内存累积引发 OutOfMemoryError,需学习如何排查其导致的内存泄漏。
关键信息:

  • 示例程序模拟 ThreadLocal 内存泄漏,在循环中不断创建线程并设置大字符串为 ThreadLocal 变量且不删除。
  • 排查步骤:捕获堆转储(可通过传递特定 JVM 参数),分析堆转储(可用 HeapHero 等工具,其利用机器学习算法检测内存泄漏模式,“Largest Objects”部分突出消耗大量堆空间的线程,“Outgoing Reference”部分显示 ThreadLocal 字符串),预防方法是使用 threadString.remove()清除 ThreadLocal 变量值。
    重要细节:
  • 示例程序中在第 3 行声明 threadString 为 ThreadLocal 变量,第 10 行无限创建新线程,第 13 行设置大字符串。
  • HeapHero 工具能检测内存泄漏并指出相关对象及来源,通过 drill down 可查看具体内容。
  • 不清除 ThreadLocal 变量会随时间累积导致应用故障,及时清除可防止。
阅读 200
0 条评论