【发布时间】:2015-11-23 12:45:30
【问题描述】:
我正面临一个类加载器泄漏,我能够在一个只有两个类和几行代码的小项目中重新生成它。它会在使用记录器 (Log4j2) 时立即发生。
问题: 多次部署应用程序时,类会一次又一次地加载,直到 PermGen 空间达到其限制。
重现步骤: Download 这个包含两个类的小型 Maven 项目。它们也如下所示。
- 在标准的 tomcat 7 上部署应用程序
- 启动 jvisualvm 并监控 tomcat 实例
- 取消部署应用程序
- 再次部署应用程序...即使您点击“执行 gc”按钮,类也不会被删除。
我已经尝试过但没有成功:
- 在非静态字段中使用记录器
- 使用“-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC”启动虚拟机
- 在 Spring bean 中定义记录器
你有什么想法,如何解决这个问题? 提前致谢!
这是上面引用的项目中包含的代码:
SpringContextInitializer.java(基于 http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/web/WebApplicationInitializer.html)
public class SpringContextInitializer implements WebApplicationInitializer {
@Override
public void onStartup(final ServletContext servletContext) throws ServletException {
servletContext.addListener(new Log4jServletContextListener());
servletContext.setAttribute("isLog4jAutoInitializationDisabled", false);
servletContext.setAttribute("log4jConfiguration", "classpath:log4j2.xml");
// Load a spring context and manage the lifecycle of the root
// application context
final AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
appContext.register(SpringConfiguration.class);
servletContext.addListener(new ContextLoaderListener(appContext));
// Enable the use of a session scope
servletContext.addListener(new RequestContextListener());
}
}
SpringConfiguration.java
@Configuration
public class SpringConfiguration {
private static final Logger LOGGER = LogManager.getLogger(SpringConfiguration.class.getName());
}
【问题讨论】:
标签: spring memory-leaks log4j log4j2