取消部署时,WebappClassLoader和Hibernate内存是否泄漏?

时间:2014-07-01 17:32:56

标签: java tomcat memory-leaks

编辑:关于此问题的Hibernate论坛主题:https://forum.hibernate.org/viewtopic.php?f=1&t=1035073

我正在使用hibernate-4.3.1ehcache-core-2.6.7c3p0-0.9.5-pre5Tomcat 7.0.27以及我在取消部署应用时遇到大量PermGen泄漏。

我已经发现,有很多类由WebappClassLoaderhere is列表固定,正如JProfiler所示。第一个数字是内存中该类对象的数量)< / p>

以下是ContextListener.contextDestroyed()中的代码:

@Override
public void contextDestroyed(ServletContextEvent event) {
    Debug.log.info("SERVER UNDEPLOY:");
    serviceManager.destroyServices();
    serviceManager = null; // this is static field :(

    for (Object o : C3P0Registry.getPooledDataSources()) {
        PooledDataSource dataSource = (PooledDataSource) o;
        try {
            Debug.log.info(String.format(
                    "-> deregistering C3P0 pool: size %s",
                    dataSource.getThreadPoolSize()));
            dataSource.close();
            Thread.sleep(500);
        } catch (SQLException e) {
            Debug.log.error(String.format(
                    "   FAILED deregistering C3P0 pool: %s",
                    dataSource.getDataSourceName()), e);
        } catch (InterruptedException e) {
        }
    }

    Debug.log.info("-> shutting down cache manager");
    CacheManager.getInstance().shutdown();

    Enumeration<Driver> drivers = DriverManager.getDrivers();
    while (drivers.hasMoreElements()) {
        Driver driver = drivers.nextElement();
        try {
            Debug.log.info(String.format(
                    "-> deregistering jdbc driver: %s", driver));
            DriverManager.deregisterDriver(driver);
        } catch (SQLException e) {
            Debug.log.error(String.format(
                    "   FAILED deregistering driver %s", driver), e);
        }
    }

    Debug.log.info("-> shutting down Hibernate factories");
    Hibernate.factory.close(); //SessionFactory
    Hibernate.factory = null; // static field :(

    Debug.log.info("-> stopping logger");
    Debug.log.info("............  SERVER stop ...................");
    ((LoggerContext) LoggerFactory.getILoggerFactory()).stop();

}

我试图在分析器中分析对象的GC根,但没有成功。任何人都可以建议为什么会这样吗?

1 个答案:

答案 0 :(得分:0)

我很高兴你在contextDestroyed(...)中接近你的数据源!

但您可能还想尝试c3p0中的两个新设置,专门用于解决Tomcat和其他基于ClassLoader的热重新部署环境中的内存泄漏问题。请参阅green box here及其中的链接。

(请升级到最新的0.9.5-pre8。这些是新功能,我不记得哪个0.9.5预发行版带来了它们。)