Spring 和 Log4j2 的类加载器泄漏
Classloader-Leak with Spring and Log4j2
我正面临类加载器泄漏,我能够在一个小项目中重新生成它,只需要两个 类 和几行代码。一旦使用记录器 (Log4j2),它就会发生。
问题:
多次部署应用程序时,类 会一次又一次地加载,直到 PermGen space 达到其限制。
重现步骤:
Download 这个小 Maven 项目包含两个 类。它们也在下面描述。
- 在标准 tomcat 7
上部署应用程序
- 启动 jvisualvm 并监控 tomcat 实例
- 取消部署应用程序
- 再次部署应用程序...即使您点击 'perform 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());
}
log4j 版本 2.4 和 2.4.1 有很多 known memory leak issues。即将发布的 log4j-2.5 版本将解决所有这些问题。
我正面临类加载器泄漏,我能够在一个小项目中重新生成它,只需要两个 类 和几行代码。一旦使用记录器 (Log4j2),它就会发生。
问题:
多次部署应用程序时,类 会一次又一次地加载,直到 PermGen space 达到其限制。
重现步骤: Download 这个小 Maven 项目包含两个 类。它们也在下面描述。
- 在标准 tomcat 7 上部署应用程序
- 启动 jvisualvm 并监控 tomcat 实例
- 取消部署应用程序
- 再次部署应用程序...即使您点击 'perform 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());
}
log4j 版本 2.4 和 2.4.1 有很多 known memory leak issues。即将发布的 log4j-2.5 版本将解决所有这些问题。