gpt4 book ai didi

java - 使用 Oracle JDBC 驱动程序 12c 的 Tomcat 7 上的内存泄漏 - oracle.jdbc.driver 线程无法停止

转载 作者:搜寻专家 更新时间:2023-11-01 00:56:26 26 4
gpt4 key购买 nike

我有一个部署到 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 驱动程序(ojdbc6.jar 或 ojdbc7.jar)的 12c 版本时才创建,因此问题仅存在。

如果我恢复使用 11.2.0.4 版本的 ojdbc6.jar,则永远不会创建线程并且永远不会出现内存泄漏警告。

我应该降级 JDBC 驱动程序(如 https://stackoverflow.com/a/9177263/4105953 中的建议)吗?

最佳答案

我发现了关于该主题的冗长讨论 here .结论是它会造成“固定大小的内存泄漏”,即后续的重新部署不会增加内存泄漏。
我没有Oracle支持访问权限,但讨论中提到的错误ID是16841748(2013年5月,现在可能已解决)。

一种可能的解决方法是在通过自定义 servlet 启动 Tomcat 时实际使用一次数据源(获取连接、执行虚拟查询、关闭连接),该 servlet 在 tomcat/conf 中配置为“启动时加载”/web.xml。这应该在您的 Web 应用程序的类加载器范围之外启动 Oracle 驱动程序线程(另请参阅 FAQ 关于驱动程序线程),从而防止“固定大小的内存泄漏”。

请注意,MySQL JDBC 驱动程序也存在类似问题,但有一个 decent solution .对于最新版本的 Oracle JDBC 驱动程序(我不知道),可能存在这样的解决方案。

关于java - 使用 Oracle JDBC 驱动程序 12c 的 Tomcat 7 上的内存泄漏 - oracle.jdbc.driver 线程无法停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26180770/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com