sql-server - MS SQL JDBC 驱动程序在 Tomcat 9 上使用 JNDI Hikari 创建内存泄漏
问题描述
我在 Tomcat 9.0.7 上使用 JNDI + HikariCP,配置如下:
<Resource name="jdbc/mydb" auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
type="javax.sql.DataSource"
minimumIdle="5"
maximumPoolSize="20"
connectionTimeout="300000"
dataSourceClassName="com.microsoft.sqlserver.jdbc.SQLServerDataSource"
dataSource.url="jdbc:sqlserver://server:1433;databaseName=mydb"
dataSource.user="fantomas"
dataSource.password="somepassword"
closeMethod="close"
/>
当我在没有部署任何 WAR 的情况下运行 tomcat 时(只是标准安装,仅此而已),我在 Catalina 日志中有以下警告:
09-May-2018 10:15:16.971 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [host-manager] appears to have started a thread named [mssql-jdbc-TimeoutTimer-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)
出了什么问题,为什么会有泄漏?我该如何解决?
UPDATE-1 Tomcat 安装的 ./lib 中的自定义库是:
ms-sql-6.4.0.jre8.jar
slf4j-api-1.7.25.jar
HikariCP-2.7.8.jar
UPDATE-2 Hikari 3.1.0 和 Tomcat 9.0.8 也有同样的问题
解决方案
有问题的线程 ( mssql-jdbc-TimeoutTimer ) 属于 MSSQL 驱动程序。它在您使用 HikariCP 而不是 Tomcat JDBC 时出现,因为 HikariCP适当地使用了 JDBC 超时 API 以提高可靠性。
这是 MSSQL 驱动程序的一个已知问题,请在此处搜索“mssql-jdbc-TimeoutTimer”。
似乎计时器是由 HikariCP 调用 MSSQL 驱动程序实现的Connection.isValid()
. 因此,您可以通过设置 a 来避免该问题connectionTestQuery
,这将禁用isValid()
.
推荐阅读
- c++ - 使用两个 while 循环的简单 C++ 代码说明
- r - 如何调整和删除交叉表图中的图例标签?
- typescript - VSCode typescript intellisense 不建议嵌套命名空间中的接口
- html - 波兰语字符有不同的权重
- php - 巧妙地解析 PHP 日期时间
- javascript - 用相似的子对象解构 JS 对象
- loops - 在 Ada 中的第一个索引之后开始的数组循环?
- php - 数组值自动增加一个设定值(例如,如果第一个是 echo $myarray[5];下一个是 echo $myarray[5+5];所以真的是 $myarray[10];)
- sql - 无法在 phpmyadmin 中显示空值,对我做错了什么有任何解释吗?
- python - Flask/Dash CSV/Excel 文件下载/输出对于不同实例中的每个用户不是唯一的