使用Oracle JDBC驱动程序12c的Tomcat 7上的内存泄漏 – oracle.j
我有一个部署到Tomcat 7.0.54的Web应用程序,它使用数据源连接到Oracle 11g数据库.数据源在META-INF / context.xml中配置,我将ojdbc7.jar放在< tomcat-install-dir> / lib中.我使用JNDI查找来检索我存储在单例中的数据源,以便每个DAO类都可以使用它.
一切都按预期工作,但是当我取消部署应用程序(通过Tomcat管理器应用程序)时,我在日志中看到: Oct 03,2014 3:06:55 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: The web application [/myapp] appears to have started a thread named [oracle.jdbc.driver.BlockSource.ThreadedCachingBlockSource.BlockReleaser] but has failed to stop it. This is very likely to create a memory leak. Oct 03,2014 3:06:57 PM org.apache.catalina.startup.HostConfig undeploy INFO: Undeploying context [/myapp] 当我调试时,我可以看到一旦访问数据库就会创建这个线程(通过数据源). 我的数据源配置: <Context antiResourceLocking="false"> <Resource name="jdbc/myapp" auth="Container" type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver" maxActive="20" maxIdle="10" maxWait="-1" username="myuser" password="mypass" url="jdbc:oracle:thin:@myserver:1521:mysid" removeAbandoned="true" removeAbandonedTimeout="10" logAbandoned="true" validationQuery="SELECT 1 FROM DUAL" testOnBorrow="true" testOnReturn="true" testWhileIdle="true" timeBetweenEvictionRunsMillis="1800000" numTestsPerEvictionRun="3" minEvictableIdleTimeMillis="1800000" /> </Context> 编辑 进一步的调查表明,无论在应用程序(或servlet)初始化期间是否访问数据源,都会出现问题. 实际上,只有在使用Oracle的JDBC驱动程序的12c版本(ojdbc6.jar或ojdbc7.jar)时才会创建有问题的线程,因此只存在问题. 如果我恢复使用ojdbc6.jar的11.2.0.4版本,则永远不会创建线程,并且永远不会出现内存泄漏警告. 我应该降级JDBC驱动程序(如https://stackoverflow.com/a/9177263/4105953中所述)吗? 解决方法我找到了关于主题 here的冗长讨论.结论是它创建了“固定大小的内存泄漏”,即随后的重新部署不会增加内存泄漏.我没有Oracle Support访问权限,但讨论中提到的错误ID是16841748(2013年5月,现在可能已解决). 一个可能的解决方法是在Tomcat通过在tomcat / conf / web.xml中配置为“load-on-startup”的自定义servlet启动时实际使用数据源一次(获取连接,执行虚拟查询,关闭连接).这应该启动Web驱动程序类加载器范围之外的Oracle驱动程序线程(另请参阅FAQ关于驱动程序线程),从而防止“固定大小的内存泄漏”. 请注意,MySQL JDBC驱动程序存在类似的问题,但有一个decent solution.对于最新版本的Oracle JDBC驱动程序(我不知道),可能存在这样的解决方案. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |