Java Log4j2 AsyncAppender线程在tomcat取消部署时未死亡,导致内存泄漏

Java Log4j2 AsyncAppender线程在tomcat取消部署时未死亡,导致内存泄漏,java,tomcat,spring-mvc,memory-leaks,log4j2,Java,Tomcat,Spring Mvc,Memory Leaks,Log4j2,我目前使用的堆栈是: log4j2rc1 Spring3.2核心和web tomcat 7.0.47 java 1.6.0_45 视窗7 我没有能力更改tomcat版本或java版本,我不希望更改log4j版本和spring版本 基本上,当我取消部署我的webapp时,我会收到一个严重的警告,上面说: SEVERE: The web application [/MyApp] appears to have started a thread named [AsyncAppender-Async

我目前使用的堆栈是:

  • log4j2rc1
  • Spring3.2核心和web
  • tomcat 7.0.47
  • java 1.6.0_45
  • 视窗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">
其中
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>

org.apache.logging.log4j.core.web.Log4jServletContextListener
log4jServletFilter
org.apache.logging.log4j.core.web.Log4jServletFilter
log4jServletFilter
/*
要求
向前地
包括
错误

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

添加下面的代码片段对我来说很有效,可以消除由于异步Appender线程即使在应用程序关闭后也没有关闭而导致的内存泄漏。 谢谢你@kipper\t

<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>

org.apache.logging.log4j.core.web.Log4jServletContextListener
log4jServletFilter
org.apache.logging.log4j.core.web.Log4jServletFilter
log4jServletFilter
/*

如果您最近遇到了这个问题,您应该注意以下几点:

如果您使用的是servlet 3.0+和tomcat>7.0.43或tomcat 8,则无需进行任何配置,您只需提供正确的maven依赖项,以使log4j2了解在webcontainer中运行的情况,如下所示(此外,我们使用slf4j):


org.slf4j

是的,它适用于servlet规范3.1。此外,我们正在等待这一问题的解决:
<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>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.30</version>
</dependency>

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.11.0</version>
</dependency>

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.11.0</version>
</dependency>

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-web</artifactId>
    <version>2.11.0</version>
</dependency>

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.11.0</version>
</dependency>