H2对Tomcat的关机挂起,使用Tomcat Datasource时内存泄漏

时间:2013-09-11 07:31:29

标签: java tomcat jdbc memory-leaks h2

这与这两个帖子有关:

基本上H2会对数据库进行锁定,即使所有连接都已关闭,因此当停止Tomcat时,它会挂起等待某个线程,该进程仍在运行。 我设法让H2不锁定数据库的唯一方法是发出语句SHUTDOWN IMMEDIATELY命令(vanilla或compact没有释放锁定。)

这是在我的ServletContextListener类中在contextDestroyed中执行的,就像这个(我已经省略了注释和日志行)

    ServletContext ctx = servletContextEvent.getServletContext();

    DataSource closeDS = databaseConnection.getDatasource();
    Connection closeConn = null;
    PreparedStatement closePS = null;
    try {
        closeConn = closeDS.getConnection();
        closePS = closeConn.prepareStatement("SHUTDOWN IMMEDIATELY");
        closePS.execute();
    } catch (Exception ex) {
    } finally {
        if (closePS != null) { 
          try { closePS.close(); } catch (SQLException ex) {} 
        }
        if (closeConn != null) { 
          try { closeConn.close(); } catch (SQLException ex) {}
        }
    }

    try {
        databaseConnection.close();
        databaseConnection = null;
        ctx.setAttribute("databaseConnection", null);
    } catch(Exception e) {
    }
    Enumeration<Driver> drivers = DriverManager.getDrivers();
    while (drivers.hasMoreElements()) {
        Driver driver = drivers.nextElement();
        try {
            DriverManager.deregisterDriver(driver);
        } catch (Exception e) {
        }
    }

现在锁被释放Tomcat停止了(虽然我仍然在日志中收到严重的内存泄漏消息)但是现在我在日志中也收到了一些错误堆栈:

INFO: Illegal access: this web application instance has been stopped already.  
  Could not load java.lang.ThreadGroup.  
  The eventual following stack trace is caused by an error thrown 
  for debugging purposes as well as to attempt to terminate 
  the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1531)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1491)
    at org.h2.engine.DatabaseCloser.reset(DatabaseCloser.java:43)
    at org.h2.engine.Database.close(Database.java:1155)
    at org.h2.engine.DatabaseCloser.run(DatabaseCloser.java:80)
10-sep-2013 13:31:41 org.apache.catalina.loader.WebappClassLoader loadClass

问题是:如何在不导致非法状态异常的情况下关闭数据库。我的代码中有什么问题可以调用shutdown命令吗? 为什么H2会出现这样的问题?我没有JBoss或Websphere的这个问题,其中应用程序也使用容器提供的数据源运行。

0 个答案:

没有答案