gpt4 book ai didi

java - Log4j2 AsyncAppender 线程不会死在 tomcat 取消部署导致内存泄漏

转载 作者:行者123 更新时间:2023-11-28 22:13:02 24 4
gpt4 key购买 nike

我现在使用的堆栈是:

  • log4j2 rc1
  • spring 3.2 核心和网络
  • tomcat 7.0.47
  • Java 1.6.0_45
  • Windows 7

我没有能力更改 tomcat 版本或 java 版本,我不想更改 log4j 版本和 spring 版本。

本质上,当我取消部署我的 webapp 时,我会收到一条严重警告:

SEVERE: The web application [/MyApp] appears to have started a thread named
[AsyncAppender-AsyncFile] but has failed to stop it. This is very likely to
create a memory leak

我可以确认它确实造成了内存泄漏,这就是我要修复的问题。

到目前为止,我已经尝试创建一个包含以下代码的自定义 ServletContextListener:

@Override
public void contextDestroyed(ServletContextEvent event) {
System.out.println("Shutting down logger");
try {
((Log4jWebSupport) event.getServletContext().getAttribute(
Log4jWebSupport.SUPPORT_ATTRIBUTE)).clearLoggerContext();
((LifeCycle) LogManager.getContext()).stop();
} catch (Exception e) {

}
}

这两行似乎都不能解决问题,但是由于我的 sysout 语句出现在 tomcat 控制台中,我可以确认这段代码正在执行。

我通过使用 Spring 设置的拦截器使用 log4j2

<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<ref bean="LoggingInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<bean id="LoggingInterceptor" class="MyLoggerClass">

拦截器工作正常,日志出现在我期望的位置。我对记录器的实现是:

private static Logger log = LogManager.getLogger("MetricLogger");

public void log(LogPayload payload) {
if(payload != null){
log.info(payload.get());
}
}

其中 LogPayload.get() 返回一个字符串。

当我在多个 webapps 中使用日志工具时,我创建了一个单独的 jar 文件,其中包含这个和记录测量的类。我已经使用 maven 将其包含在内,并将其编译到我部署到 tomcat 的最终 war 文件中。此 war 文件包含在每个应用程序的基础上,不包含在全局 tomcat/lib 文件夹中。

有没有人知道我为什么会遇到内存泄漏问题以及解决此问题的可能解决方案?

非常感谢您的帮助,如果您需要更多信息,请告诉我。

最佳答案

目前我找到的解决方案是我需要在 web.xml 中包含以下代码段。

<listener>
<listener-class>org.apache.logging.log4j.core.web.Log4jServletContextListener</listener-class>
</listener>

<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.core.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>

这是特定于 servlet 规范 2.5 的。这似乎解决了内存泄漏问题。

关于java - Log4j2 AsyncAppender 线程不会死在 tomcat 取消部署导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23359668/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com