jdbc内存泄漏,解决方法

问题

 

警告: Web应用程序 [Mail_1] 注册了JDBC驱动程序 [com.mysql.cj.jdbc.Driver],但在Web应用程序停止时无法注销它。 为防止内存泄漏,JDBC驱动程序已被强制取消注册。
七月 05, 2026 1:56:24 上午 org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
警告: Web应用程序[Mail_1]似乎启动了一个名为[mysql-cj-abandoned-connection-cleanup]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪:[
 java.lang.Object.wait(Native Method)
 java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
 com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:91)
 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
 java.lang.Thread.run(Thread.java:748)]
七月 05, 2026 1:56:24 上午 org.apache.catalina.loader.WebappClassLoaderBase checkStateForResourceLoading
信息: 非法访问:此Web应用程序实例已停止。无法加载[]。为了调试以及终止导致非法访问的线程,将抛出以下堆栈跟踪。
java.lang.IllegalStateException: 非法访问:此Web应用程序实例已停止。无法加载[]。为了调试以及终止导致非法访问的线程,将抛出以下堆栈跟踪。
at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1427)
at org.apache.catalina.loader.WebappClassLoaderBase.getResource(WebappClassLoaderBase.java:1052)
at com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.checkThreadContextClassLoader(AbandonedConnectionCleanupThread.java:123)
at com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:90)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

 

解决方法

1

我所做的只是把mysql-connector-java-5.1.31-bin.jar放在$CATALINA_HOME/lib里。不修改server.xml

 

2

Stack Overflow用户

发布于 2014-07-20 11:53:00

您的应用程序没有缺陷。这是JDBC的设计。当首次创建数据库连接时,JDBC驱动程序将由webapp加载和注册。

这意味着驱动程序加载了web应用程序类加载器。在取消部署时,驱动程序不会被取消注册,这反过来又会阻止您的webapp类从GC中删除。这有效地造成了内存泄漏。

为了防止这种特定的内存泄漏,您应该编辑tomcat/conf/server.xml并更改

 

<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />

<Listener 
className="org.apache.catalina.core.JreMemoryLeakPreventionListener"
classesToInitialize="com.mysql.jdbc.NonRegisteringDriver" />
  • 对于mysql连接器-java-8.0.x,使用com.mysql.cj.jdbc.NonRegisteringDriver代替

将JDBC驱动程序从webapp工件中排除,并将其放到tomcat/lib目录中。现在,JDBC驱动程序在启动时由Tomcat加载,并且没有链接到任何webapp类加载器。

为什么要修改server.xml?

另一个内存泄漏是由于MySQL的“废弃的连接清理线程”造成的。这个线程从第一个请求开始,并保存对webapp的类加载器的引用。使用classesToInitialize,您也可以防止内存泄漏。

 

 

posted @ 2026-07-05 02:01  涂山树下  阅读(4)  评论(1)    收藏  举报