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,您也可以防止内存泄漏。

浙公网安备 33010602011771号