Драйвер JDBC MS SQL создает утечку памяти с помощью JNDI Hikari на Tomcat 9 - PullRequest
0 голосов
/ 09 мая 2018

Я использую JNDI + HikariCP на Tomcat 9.0.7 со следующей конфигурацией:

 <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"
      />

Когда я запускаю tomcat без развернутой моей WAR (просто стандартная установка, ничего более), в журнале 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 Пользовательские библиотеки в ./lib установки Tomcat:

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

Ответы [ 2 ]

0 голосов
/ 24 мая 2018

Рассматриваемый поток ( mssql-jdbc-TimeoutTimer ) принадлежит драйверу MSSQL. Он появляется, когда вы используете HikariCP, но не Tomcat JDBC, потому что HikariCP соответственно использует API времени ожидания JDBC для надежности.

Это известная проблема с драйвером MSSQL, ищите 'mssql-jdbc-TimeoutTimer' здесь .

Похоже, что таймер запускается при вызове HikariCP к реализации драйвера MSSQL Connection.isValid(). Таким образом, вы можете избежать этой проблемы, установив connectionTestQuery, что отключит использование isValid().

0 голосов
/ 23 мая 2018

Связанная проблема с аналогичной утечкой сообщена hikari , и похоже, что окончательное решение использует не фабрику JNDI Hikari, а источник данных Tomcat

Попробуйте изменить фабрику на:

factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"

EDIT

Вы создали новый выпуск для Hikari

...