You need to enable JavaScript to run this app. Tomcat9通过JNDI获取数据库连接,停止应用报内存泄漏是否需关闭DataSource
优惠活动
大模型
产品
解决方案
定价
更多

Tomcat9通过JNDI获取数据库连接,停止应用报内存泄漏是否需关闭DataSource

解决方案

核心结论

你不需要主动关闭DataSource或InitialContext对象,二者均由Tomcat容器负责生命周期管理,归属权不属于当前Web应用,手动关闭反而可能导致容器运行异常。

具体修复步骤

  • 修正pom.xml依赖的scope配置:
    当前你的jsp-api、jstl依赖未设置<scope>provided</scope>,会被Maven自动打入WEB-INF/lib目录,和Tomcat自带的同类型类库冲突,导致类加载器无法在应用停止时被回收,引发内存泄漏。修改依赖如下:
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2.1-b03</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
        <scope>provided</scope>
    </dependency>
    
  • 确保所有数据库资源被正确释放:
    你从getConnection()拿到的Connection对象是连接池的借用实例,用完必须调用close()归还到连接池,否则连接池会一直持有活跃连接,应用停止时Tomcat就会报JDBC连接泄漏的警告。推荐用JDK7+自带的try-with-resources语法自动关闭资源,避免手动遗漏:
    // 业务代码使用连接的标准写法
    try (Connection conn = YourUtils.getConnection();
         PreparedStatement stmt = conn.prepareStatement("你的SQL语句");
         ResultSet rs = stmt.executeQuery()) {
        // 处理业务逻辑
    } catch (SQLException e) {
        // 异常处理逻辑
    }
    
  • 可选优化:
    你的getConnection()方法不需要每次都执行JNDI lookup查找DataSource,DataSource是容器管理的单例实例,你可以在应用启动时通过ServletContextListener一次性查找缓存,后续直接复用即可,减少不必要的JNDI查询开销。

额外排查建议

如果做完上述修改仍有警告,可以在Tomcat的conf/server.xml的<Host>标签下添加内置的泄漏预防监听器:

<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />

该监听器会自动处理JDBC驱动注册、线程上下文类加载器等常见的JRE层面内存泄漏问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 11:15:01