【问题标题】:WebappClassLoader and Hibernate memory leaks when undeploying?卸载时 WebappClassLoader 和 Hibernate 内存泄漏?
【发布时间】:2014-07-01 17:32:56
【问题描述】:

编辑:关于这个问题的 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 泄漏。

我发现,WebappClassLoader 固定了很多类(here is 列表,如 JProfiler 所示。第一个数字是该类在内存中的对象数)

这是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 根,但没有成功。谁能提出为什么会这样?

【问题讨论】:

  • 你已经通过 Tomcat 浏览了 MemoryLeakProtection 吗?,阅读更多 @wiki.apache.org/tomcat/MemoryLeakProtection
  • 是的。有问题的代码会注销 JDBC 驱动程序,我已经知道静态变量以及它们如何保存东西。我的应用本身不创建线程,也不使用 ClassLoaders。

标签: java tomcat memory-leaks


【解决方案1】:

很高兴您在 contextDestroyed(...) 中关闭()您的数据源!

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

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

【讨论】:

猜你喜欢
  • 2021-04-05
  • 1970-01-01
  • 1970-01-01
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
  • 2017-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多