一尘不染

Tomcat Guice / JDBC内存泄漏

tomcat

由于Tomcat中的孤立线程,我遇到了内存泄漏。特别是,Guice和JDBC驱动程序似乎没有关闭线程。

Aug 8, 2012 4:09:19 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: A web application appears to have started a thread named [com.google.inject.internal.util.$Finalizer] but has failed to stop it. This is very likely to create a memory leak.
Aug 8, 2012 4:09:19 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: A web application appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak.

我知道这与其他问题,但是就我而言,“不必担心”的答案是不够的,因为它给我带来了麻烦。我的CI服务器会定期更新此应用程序,重新加载6-10次后,由于Tomcat内存不足,CI服务器将挂起。

我需要能够清理这些孤立的线程,以便可以更可靠地运行CI服务器。任何帮助,将不胜感激!


阅读 333

收藏
2020-06-16

共1个答案

一尘不染

我自己解决了这个问题。与其他答案相反,我不建议发出该t.stop()命令。此方法已被弃用,这是有充分理由的。请参考Oracle这样做的原因

但是,有一种解决方案可以消除此错误,而无需诉诸t.stop()

您可以使用提供的大多数代码@Oso,只需替换以下部分

Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);
for(Thread t:threadArray) {
    if(t.getName().contains("Abandoned connection cleanup thread")) {
        synchronized(t) {
            t.stop(); //don't complain, it works
        }
    }
}

使用MySQL驱动程序提供的以下方法替换它:

try {
    AbandonedConnectionCleanupThread.shutdown();
} catch (InterruptedException e) {
    logger.warn("SEVERE problem cleaning up: " + e.getMessage());
    e.printStackTrace();
}

这应该正确地关闭线程,并且错误应该消失。

2020-06-16