Oracle驱动程序的内存泄漏 - Tomcat的(Oracle driver memory le

2019-07-04 16:57发布

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

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

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

服务器控制台显示:

17505 INFO org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - 关闭JPA EntityManagerFactory的持久性单元 'myManager' 17515个INFO 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中](值[类oracle.sql.AnyDataFactory]),但未能web应用停止时将其删除。 线程将要更新随着时间的推移,试图避免可能的内存泄漏。 2012年12月6日下午6时41分29秒org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks重度:Web应用程序[/对myApp]建立一个ThreadLocal类型[java.lang.ThreadLocal中](值[java.lang中的键。 ThreadLocal的@ d73b31])和类型[java.lang.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的@ 13aae39])和类型[java.lang.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中(值类oracle.sql.AnyDataFactory])的值,但失败的Web应用程序停止时将其删除。 线程将要更新随着时间的推移,试图避免可能的内存泄漏。 2012年12月6日下午6点41分34秒org.apache.catalina.startup.HostConfig deleteRedeployResources INFO:取消部署上下文[/对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();

Answer 1:

想通了这个问题...托尼有一个很好的建议(但取消注册驱动程序意味着,当应用程序重新加载驱动程序不再可用!)。

在我们的例子中,我们偶然地被包括ojdbc6.jar我们的Web App和在Tomcat / lib目录。 这pressumably引起Tomcat使用我们的类加载器来创建对象。 因此,当我们的应用程序正在卸载Tomcat的DBCP池仍然有打开的句柄类在我们的应用程序。

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



Answer 2:

在监听你也取消注册JDBC驱动程序(即ojdbc5.jar或者你使用的是什么)。

见这对代码段,这样的问题。



文章来源: Oracle driver memory leak - Tomcat