【发布时间】:2014-07-01 17:32:56
【问题描述】:
编辑:关于这个问题的 Hibernate 论坛主题:https://forum.hibernate.org/viewtopic.php?f=1&t=1035073
我正在使用 hibernate-4.3.1、ehcache-core-2.6.7、c3p0-0.9.5-pre5 和 Tomcat 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