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

升级Tomcat9后重部署Spring Boot应用触发ehcache致JVM崩溃

问题诊断与解决方案

核心原因分析

  • Tomcat 9.0.x 与 Ehcache 3.9.0 的类加载器兼容性冲突:Tomcat 9 调整了类加载机制,尤其是Web应用重部署时的类卸载逻辑,而Ehcache 3.9.0存在未正确释放的全局资源(如缓存管理器实例、内存映射文件),导致类加载器无法被回收,触发JVM层面的halt错误。
  • 多版本应用缓存资源抢占:同一Tomcat实例运行两个同应用不同版本时,若Ehcache使用全局静态实例或未隔离的配置,重部署时新旧版本的缓存组件会出现资源冲突,引发底层VM错误。
  • Ehcache 3.9.0 已知Bug:该版本存在类加载器相关的资源泄漏问题,在Web容器重部署场景下易触发JVM halt异常。

分步解决方案

  1. 升级Ehcache版本
    直接升级至Ehcache 3.10.0及以上版本,官方后续版本修复了多个类加载器泄漏和Web容器部署相关Bug,包含针对Tomcat 9的兼容性优化。

  2. 配置Ehcache类加载器隔离
    在Spring Boot应用的Ehcache配置中,明确指定使用当前Web应用的类加载器,避免依赖全局类加载器:

    CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
        .classLoader(this.getClass().getClassLoader())
        .build(true);
    

    或在ehcache.xml中添加类加载器配置:

    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="ehcache.xsd">
        <classLoader>${java.class.path}</classLoader>
        <!-- 其他缓存配置 -->
    </config>
    
  3. 优化Tomcat资源回收配置
    在Tomcat的conf/context.xml中添加以下配置,增强类加载器回收能力:

    <Context>
        <Loader useSystemClassLoaderAsParent="false" clearReferencesStopTimerThreads="true"/>
        <Resources cachingAllowed="true" cacheMaxSize="100000"/>
    </Context>
    

    该配置会强制Tomcat在应用卸载时清理线程和类加载器引用,降低资源泄漏风险。

  4. 隔离多版本应用缓存实例
    确保两个不同版本的应用使用独立的CacheManager实例,避免共享全局缓存资源:

    • 在Spring Boot中通过@Bean自定义CacheManager,为每个应用指定唯一的缓存名称前缀或独立配置:
      @Bean
      public CacheManager ehCacheManager() {
          return CacheManagerBuilder.newCacheManagerBuilder()
              .withCache("getAccountSettingByState", CacheConfigurationBuilder.newCacheConfigurationBuilder(
                  String.class, AccountSetting.class, ResourcePoolsBuilder.heap(100)))
              .build(true);
      }
      
  5. 排查JVM崩溃日志
    收集JVM崩溃生成的hs_err_pid.log文件,查看错误栈和内存地址信息,确认是否为Ehcache内存映射文件(MappedByteBuffer)未释放导致的问题。如果是,可临时禁用磁盘存储排查:

    <cache alias="getAccountSettingByState">
        <key-type>java.lang.String</key-type>
        <value-type>com.example.AccountSetting</value-type>
        <resources>
            <heap unit="entries">100</heap>
            <!-- 临时禁用磁盘存储 -->
            <!-- <disk unit="MB">10</disk> -->
        </resources>
    </cache>
    

已知问题参考

  • Ehcache官方在3.9.0版本后修复了CacheManager未正确关闭导致的类加载器泄漏问题(Issue #2978),该问题在Web容器频繁重部署场景下会触发JVM资源耗尽错误。
  • Tomcat 9.0.31存在Web应用类卸载相关的小Bug,升级至Tomcat 9.0.40及以上版本可获得更稳定的类加载器回收逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:03:23