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

Spring Boot 2.5部署Tomcat9重部署时日志相关永久代内存泄漏问题

Spring Boot 2.5 war包部署Tomcat 9类加载器泄漏解决方案

配置补全步骤

1. 日志框架生命周期托管配置

你已添加log4j-web依赖但未生效,是因为缺少显式的容器监听器配置,需要在项目WEB-INF/web.xml中添加对应日志框架的生命周期监听器,由Tomcat在应用卸载时主动销毁日志上下文:

  • Log4j2 配置:
<listener>
    <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<context-param>
    <param-name>log4j2.isWebApp</param-name>
    <param-value>true</param-value>
</context-param>
  • Logback 配置:
<listener>
    <listener-class>ch.qos.logback.classic.servlet.LogbackServletContextListener</listener-class>
</listener>

同时在application.properties中禁用Spring Boot自带的日志自动初始化,避免重复注册资源:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.logging.LoggingAutoConfiguration

2. 开启JVM类卸载参数

你观察到无强引用但ParallelWebappClassLoader实例残留,大概率是未开启JVM类卸载开关,需要在CATALINA_OPTS中补充以下参数:

# 通用类卸载参数
-XX:+ClassUnloading
-XX:+ClassUnloadingWithConcurrentMark
# 若使用CMS垃圾回收器额外添加
-XX:+CMSClassUnloadingEnabled
# 若使用JDK 8+ 还可添加元空间回收参数
-XX:MetaspaceSize=128M
-XX:MaxMetaspaceSize=512M

Java 8之后永久代被元空间替代,默认不会主动卸载未使用的类,只有开启上述参数后,无引用的类加载器关联的类才会被GC回收。

3. Tomcat容器配置优化

在Tomcat的conf/server.xml中补充配置,提升重部署时的资源清理效率:

<Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true" undeployOldVersions="true">
    <Context path="" reloadable="true" antiResourceLocking="true" />
    <!-- 原有其他配置 -->
</Host>

额外排查方向

如果完成上述配置后仍有泄漏,可优先排查以下场景:

  • 应用内是否有自定义线程池未在ServletContextListener的销毁方法中主动关闭,存活线程的上下文类加载器会持有ParallelWebappClassLoader的引用
  • 是否引入了包含静态缓存的第三方组件,缓存中持有应用内类的实例,未在应用卸载时主动清空缓存
  • 是否有自定义的JMX Bean未在应用卸载时主动注销,JVM的MBeanServer会持有Bean的强引用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 02:45:03