1.問題描述
本地Windows環境開發的Springboot項目同樣的mysql版本,jdk版本,tomcat版本,本地運行沒有任何問題,發布到阿里云服務器上時報以下問題:
06-May-2025 20:06:12.842 警告 [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc Web應用程序 [xxxxx-admin] 注冊了JDBC驅動程序 [com.alibaba.druid.proxy.DruidDriver],但在Web應用程序停止時無法注銷它。 為防止內存泄漏,JDBC驅動程序已被強制取消注冊。
06-May-2025 20:06:12.842 警告 [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc Web應用程序 [xxxxx-admin] 注冊了JDBC驅動程序 [com.mysql.jdbc.Driver],但在Web應用程序停止時無法注銷它。 為防止內存泄漏,JDBC驅動程序已被強制取消注冊。
06-May-2025 20:06:12.852 警告 [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads Web應用程序[xxxxx-admin]似乎啟動了一個名為[crmeb-scheduled-task-pool-1]的線程,但未能停止它。這很可能會造成內存泄漏。線程的堆棧跟蹤:[
?sun.misc.Unsafe.park(Native Method)
?java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
?java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
?java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
?java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
?java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
?java.lang.Thread.run(Thread.java:748)]
和
以上異常信息,上網查找了很多,終于成功解決。
解決辦法:
手動配置監聽器,用來在Tomcat關閉時取消注冊JDBC驅動程序,并將線程停止
編寫自定義監聽器
代碼如下:
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
//mysql8及以上用?com.mysql.cj
import com.mysql.jdbc.AbandonedConnectionCleanupThread;
//import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
@WebListener
public class DriverMangerListener implements ServletContextListener {
? ? public void contextInitialized(ServletContextEvent sce) {
? ? }
? ? public void contextDestroyed(ServletContextEvent sce) {
? ? ? ? AbandonedConnectionCleanupThread.uncheckedShutdown();
? ? ? ? Enumeration<Driver> enumeration = DriverManager.getDrivers();
? ? ? ? while (enumeration.hasMoreElements()) {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? DriverManager.deregisterDriver(enumeration.nextElement());
? ? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
我的是Springboot項目直接用@WebListener注解即可,要是ssm或者springmvc項目的話,在web.xml中添加以下代碼注冊該listener即可,注意類的路徑以及該配置所在文件中的位置。
<listener><listener-class>com.ssm.util.DriverMangerListener</listener-class> </listener>
?