Tomcat关闭时报错【驱动程序已被强制取消注册】【内存泄漏】【连接未能停止】-问题

  • Post author:
  • Post category:其他


Tomcat关闭时报错 内存泄漏问题



报错问题

详细错误见下代码

24-Nov-2020 21:24:22.484 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [demo] registered the JDBC driver [com.alibaba.druid.proxy.DruidDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
24-Nov-2020 21:24:22.484 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [demo] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
24-Nov-2020 21:24:22.485 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [mysql-cj-abandoned-connection-cleanup] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 java.lang.Object.wait(Native Method)
 java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
 com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:80)
 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
 java.lang.Thread.run(Thread.java:748)
24-Nov-2020 21:24:22.485 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [Druid-ConnectionPool-Create-730379684] 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.park(LockSupport.java:175)
 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
 com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:1824)
24-Nov-2020 21:24:22.486 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [Druid-ConnectionPool-Destroy-730379684] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 java.lang.Thread.sleep(Native Method)
 com.alibaba.druid.pool.DruidDataSource$DestroyConnectionThread.run(DruidDataSource.java:1898)



问题描述

web应用程序[demo]注册了JDBC驱动程序[com.mysql.jdbc]。但是当web应用程序停止时无法注销它。为了防止内存泄漏,JDBC驱动程序已被强制取消注册。

web应用程序[演示]似乎已经启动了一个名为[Druid-ConnectionPool-Destroy-730379684]的线程,但未能停止它。这很可能会造成内存泄漏。线程堆栈轨迹:



使用环境

Tomcat Tomcat 8.5.31 + connector-5.1.49 +mysql-5.7 +druid-1.0.9



问题排查

对于一个新手来说,一头雾水,感觉网上瞧一瞧。哇,好多人跟我一样,并且答案就那么几个,全是复制粘贴,每个人的环境也不同,全都试了一遍,也没解决,还是有问题。虽然运行的时候没有问题,但是好恶心人啊。。。必须解决


主要有两个问题,一个是驱动,一个是线程问题。

然后我将网上的代码copy下来,搞监听器,在程序停止时去处理关闭他们; copy下来后,第一个问题出现了,

AbandonedConnectionCleanupThread这个类找不到,看了下导包路径,是在connector连接中,于是马上想到可能 mysql驱动版本问题,然后去中央仓库下载了connector-5.1.49 ,在这个驱动中找到了com.mysql.jdbc.AbandonedConnectionCleanupThread类,但是网上还有com.mysql.cj.jdbc.AbandonedConnectionCleanupThread这个类,都一样的,这个是更高版本的驱动;

然后接着往下走,还报错,AbandonedConnectionCleanupThread.Shutdown(); what ?竟然没有参数,我看别人的都不用传参啊,我的驱动调用这个方法必须传参啊,搞死!!!

在这里插入图片描述

然后进去看下方法源码:只有调用了shutDown方法,ok原来如此,然后修改一通,搞定不报错了,配置好监听器,赶紧运行一下试试

在这里插入图片描述

我擦,驱动问题没有了,但是连接还有问题,到底是哪的问题咧,然后一直没搞定,请教高人啊!!!

4-Nov-2020 21:57:28.084 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [Druid-ConnectionPool-Create-1926858734] 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.park(LockSupport.java:175)
 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
 com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:1824)
24-Nov-2020 21:57:28.085 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [Druid-ConnectionPool-Destroy-1926858734] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 java.lang.Thread.sleep(Native Method)
 com.alibaba.druid.pool.DruidDataSource$DestroyConnectionThread.run(DruidDataSource.java:1898)
24-Nov-2020 21:57:28.097 信息 [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-80"]
24-Nov-2020 21:57:28.100 信息 [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-8009"]
24-Nov-2020 21:57:28.103 信息 [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-80"]
24-Nov-2020 21:57:28.104 信息 [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-8009"]

最后高人给我指点,可能是我连接获取有问题,自己写的JDBCUtil,用的DataSource,让我换DruidDataSource,

dds = (DruidDataSource) DruidDataSourceFactory.createDataSource(pro);

最后,在监听器那里关闭的时候,把这个连接池也关闭掉,修改后,赶紧试一下,卧槽,ok解决了。

贴一下代码,也是在别人的基础上修改来的;

加了这么一句JDBCUtil.getDataSource().close();问题解决了,搞了我一天,哎。。。

public class MyContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        System.out.println("webService start");
    }

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        System.out.println("webService stop");
        try {
            while(DriverManager.getDrivers().hasMoreElements()) {
                DriverManager.deregisterDriver(DriverManager.getDrivers().nextElement());
            }
            System.out.println("jdbc Driver close");
            AbandonedConnectionCleanupThread.checkedShutdown();
            JDBCUtil.getDataSource().close();
            System.out.println("clean thread success");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}



在web.xml中配置

<listener>
        <listener-class>com.javasm.MyContextListener</listener-class>
    </listener>

OK,完美 最后,高人就是高人啊!菜鸡就是菜鸡…

在这里插入图片描述



版权声明:本文为weixin_43102797原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。