6

我们使用的是 tomcat-7.0.33。使用 tomcat JNDI 数据源的 Spring 3.0.1 和 JPA。后端使用 ojdbc6.jar(最新)的 Oracle 10g。

当我们尝试取消部署应用程序时,一些 Oracle 类似乎正在泄漏。我在使用较旧的 ojdbc14.jar 驱动程序时看不到这一点,但我们不能使用它们,因为我们正在迁移到需要较新驱动程序的 Oracle 11g。我猜这是Oracle驱动程序中的错误?我能做些什么来清理这些资源吗?我试过关闭数据库连接池和其他东西无济于事......

不使用Tomcat的连接池会更好吗?我们宁愿让服务器连接到数据库,但如果有必要我们可以自己做......

服务器控制台显示:

17505 信息 org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - 关闭持久性单元“myManager”的 JPA EntityManagerFactory 17515 信息 org.apache.tiles.access.TilesAccess - 删除上下文的 TilesContext:org.springframework.web.servlet.view.tiles2。 SpringTilesApplicationContextFactory$SpringWildcardServletTilesApplicationContext 2012 年 12 月 6 日下午 6:41:29 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks 严重:Web 应用程序 [/myApp] 创建了一个 ThreadLocal,其键类型为 [java.lang.ThreadLocal](值 [java .lang.ThreadLocal@1468544])和 [java.lang.Class] 类型的值(值 [class oracle.sql.AnyDataFactory]),但在 Web 应用程序停止时无法将其删除。线程将随着时间的推移而更新,以尝试避免可能的内存泄漏。2012 年 12 月 6 日下午 6:41:29 组织。apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks 严重:Web 应用程序 [/myApp] 创建了一个 ThreadLocal,其键类型为 [java.lang.ThreadLocal](值 [java.lang.ThreadLocal@d73b31]),值类型为 [java .lang.Class](值 [class oracle.sql.TypeDescriptorFactory])但在 Web 应用程序停止时未能将其删除。线程将随着时间的推移而更新,以尝试避免可能的内存泄漏。2012 年 12 月 6 日下午 6:41:29 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks 严重:Web 应用程序 [/myApp] 创建了一个 ThreadLocal,其键类型为 [java.lang.ThreadLocal](值 [java.lang. ThreadLocal@13​​aae39])和类型为 [java.lang.Class] 的值(值 [class oracle.sql.TypeDescriptorFactory]),但在 Web 应用程序停止时未能将其删除。线程将随着时间的推移而更新,以尝试避免可能的内存泄漏。2012 年 12 月 6 日下午 6:41:29 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks 严重:Web 应用程序 [/myApp] 创建了一个 ThreadLocal,其键类型为 [java.lang.ThreadLocal](值 [java.lang. ThreadLocal@18443b1]) 和 [java.lang.Class] 类型的值(值 [class oracle.sql.AnyDataFactory]),但在 Web 应用程序停止时无法将其删除。线程将随着时间的推移而更新,以尝试避免可能的内存泄漏。2012 年 12 月 6 日下午 6:41:34 org.apache.catalina.startup.HostConfig deleteRedeployResources 信息:取消部署上下文 [/myApp] Web 应用程序 [/myApp] 创建了一个 ThreadLocal,其键类型为 [java.lang.ThreadLocal](值 [java.lang.ThreadLocal@18443b1]),值类型为 [java.lang.Class](值 [class oracle .sql.AnyDataFactory]) 但在 Web 应用程序停止时未能将其删除。线程将随着时间的推移而更新,以尝试避免可能的内存泄漏。2012 年 12 月 6 日下午 6:41:34 org.apache.catalina.startup.HostConfig deleteRedeployResources 信息:取消部署上下文 [/myApp] Web 应用程序 [/myApp] 创建了一个 ThreadLocal,其键类型为 [java.lang.ThreadLocal](值 [java.lang.ThreadLocal@18443b1]),值类型为 [java.lang.Class](值 [class oracle .sql.AnyDataFactory]) 但在 Web 应用程序停止时未能将其删除。线程将随着时间的推移而更新,以尝试避免可能的内存泄漏。2012 年 12 月 6 日下午 6:41:34 org.apache.catalina.startup.HostConfig deleteRedeployResources 信息:取消部署上下文 [/myApp]

我尝试添加一个 ContextListener 来手动关闭我们的 DBCP 连接,但这并没有帮助。

InitialContext initial = new InitialContext();

DataSource ds = (DataSource) initial.lookup("java:/comp/env/jdbc/myDS");

if (ds.getConnection() == null) {
    throw new RuntimeException("I failed to find the datasource");
}

LOG.debug("Found datasource.  Closing...");
BasicDataSource bds = (BasicDataSource) ds;

bds.close();
4

2 回答 2

9

找出问题所在... Toni 有一个很好的建议(但取消注册驱动程序意味着当应用程序重新加载时驱动程序不再可用!)。

在我们的例子中,我们不小心将 ojdbc6.jar 包含在我们的 Web 应用程序和 Tomcat/lib 目录中。这可能导致 Tomcat 使用我们的类加载器来创建对象。因此,当我们的应用程序被卸载时,Tomcat 的 DBCP 池仍然有我们应用程序中类的打开句柄。

从我们的 WEB-INF/lib 中删除 ojdbc6.jar 解决了这个问题。

于 2012-12-12T20:44:46.583 回答
0

在侦听器中,您还必须取消注册 JDBC 驱动程序(即 ojdbc5.jar 或您正在使用的)。

有关代码片段,请参阅SO 问题。

于 2012-12-07T06:55:43.617 回答