Web应用程序[]似乎已启动名为[Abandoned connection cleanup thread]的线程com.mysql.jdbc.AbandonedConnectionCleanupThread

时间:2014-09-06 11:57:54

标签: mysql spring jdbc memory-leaks

在我的网络开发过程中,我只是在我的eclipse IDE中关闭我的网络应用程序,大约一分钟,我刚刚在我的eclipse控制台中看到了警告

WARNING: The web application [/Spring.MVC] 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.
Sep 06, 2014 8:31:55 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
WARNING: The web application [/Spring.MVC] 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. Stack trace of thread:
 java.lang.Object.wait(Native Method)
 java.lang.ref.ReferenceQueue.remove(Unknown Source)
 com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:40)
Sep 06, 2014 8:32:00 PM org.apache.catalina.core.ApplicationContext log
INFO: No Spring WebApplicationInitializer types detected on classpath
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Sep 06, 2014 8:32:00 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
Sep 06, 2014 8:32:03 PM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [
    name: personPU
    ...]

到目前为止它没有造成任何内存泄漏,我检查了我的VisualVM,一切正常,但是当我搜索更多关于这个东西时,我发现这个警告是由MySQL驱动程序没有释放资源或没有关闭引起的正确(我不知道该怎么说)我最后在SO related issue

这篇文章中结束了

并且OP是对的“不要担心它”的答案是不够的。这个警告困扰我,因为它可能会给我一些未来的持久性问题,这让我很担心,我尝试了OP编写的代码,但我遇到了问题什么库我应该使用这个代码工作。这就是我的目标......

import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.hibernate.annotations.common.util.impl.LoggerFactory;
import com.mysql.jdbc.AbandonedConnectionCleanupThread;
@WebListener
public class ContextFinalizer implements ServletContextListener {

private static final Logger LOGGER = LoggerFactory.getLogger(ContextFinalizer.class);

public void contextInitialized(ServletContextEvent sce) {
}

public void contextDestroyed(ServletContextEvent sce) {
    Enumeration<Driver> drivers = DriverManager.getDrivers();
    Driver d = null;
    while (drivers.hasMoreElements()) {
        try {
            d = drivers.nextElement();
            DriverManager.deregisterDriver(d);
            LOGGER.warn(String.format("Driver %s deregistered", d));
        }
        catch (SQLException ex) {
            LOGGER.warn(String.format("Error deregistering driver %s", d), ex);
        }
    }
    try {
        AbandonedConnectionCleanupThread.shutdown();
    }
    catch (InterruptedException e) {
        logger.warn("SEVERE problem cleaning up: " + e.getMessage());
        e.printStackTrace();
    }
  }
}

我只是想知道我需要哪些库,或者如果我使用正确的库来正确实现这一点,我甚至不知道我应该使用什么Logger,谢谢你的帮助,

3 个答案:

答案 0 :(得分:25)

this answer。似乎MySQL驱动程序应该在应用程序之间共享{$TOMCAT]/lib。检查每个应用程序是否包含它。至少它对我有用,我已经能够删除警告。

如果您使用Maven标记所提供的依赖项。


更新:
根本原因是Tomcat在垃圾收集驱动程序时遇到问题,因为它是在几个应用程序共有的单例中注册的。关闭一个应用程序不允许Tomcat释放驱动程序。请参阅此answer

答案 1 :(得分:1)

对我来说,我停止mysql(服务mysql启动),然后停止bin文件夹中的tomcat(./shutdown.sh),问题已解决。

答案 2 :(得分:0)

这对我有用

在我的案例中,问题涉及弹性搜索。

从邮递员发送 Delete 请求到下面的端点,然后重新启动您的应用程序。

char[] newChars = new char[chars.length];
int left = 0;
int right = chars.length;

for (char c : chars) {
  if (c == '!') {
    newChars[left++] = c;
  } else {
    newChars[--right] = c;
  }
}

// Reverse the "otherSymbols".
for (int i = right, j = newChars.length - 1; i < j; ++i, --j) {
  char tmp = newChars[i];
  newChars[i] = newChars[j];
  newChars[j] = tmp;
}

return new String(newChars);