You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tomcat 10关闭时报Log4j 2 ThreadLocal内存泄漏错误该如何解决?

问题根因
  • 依赖适配不兼容:Tomcat 10 属于Jakarta EE 9及以上版本,全面使用jakarta.servlet.*包替代了旧的javax.servlet.*包,你使用的Log4j 2.14.1版本的log4j-web依赖仅支持javax.servlet规范,无法在Tomcat 10环境中正常注册上下文监听器,导致应用关闭时Log4j不会主动清理内部持有的ThreadLocal资源。你之前尝试把jakarta.servlet相关jar放到tomcat/lib目录无效,就是因为问题并非缺少Servlet包,而是Log4j的web适配层不支持Jakarta Servlet规范导致的。
  • Log4j2默认开启线程本地缓存优化:为了提升日志写入性能,Log4j2默认会用ThreadLocal缓存MutableLogEvent、ReusableSimpleMessage、日期格式化器等可复用对象,正常关闭流程会自动清理这些缓存,监听器失效后缓存对象残留,就会被Tomcat的内存泄漏检测机制捕获,输出你看到的报错日志。
解决方案
  1. 替换适配Jakarta Servlet的Log4j依赖
    把pom.xml中原有log4j-web依赖替换为适配Jakarta规范的版本,同时建议升级Log4j2到2.17.2及以上稳定版本,同时修复已知的安全漏洞:
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-jakarta-web</artifactId>
    <version>2.17.2</version>
</dependency>
  1. 调整Log4j2配置适配web环境关闭逻辑
    在你的log4j2.xml的<Configuration>标签上添加shutdownHook="disable"属性,禁用JVM层面的默认关闭钩子,交由web上下文监听器统一处理资源销毁,避免冲突:
<Configuration shutdownHook="disable">
<!-- 原有配置内容保持不变 -->
</Configuration>
  1. (可选)无需极致性能可直接关闭ThreadLocal缓存
    如果你的应用对日志写入性能要求不高,可以直接在Tomcat的启动参数中添加如下配置,彻底禁用Log4j2的ThreadLocal缓存优化,从根源避免这类内存泄漏问题:
-Dlog4j2.enableThreadlocals=false

内容的提问来源于stack exchange,提问作者laing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 00:45:04