我有一个谷歌为此,看了多个建议,似乎没有任何帮助。

我有一个使用MDC的JAX-RS应用程序,当命中一个端点时,它会设置一个transactionId以便于调试。但是,当我停止或重新启动Tomcat时,日志中会填满这样的条目:

2014年9月27日09:42:14.858严重[localhost-startStop-2] org.apache.catalina.loader.WebappClassLoader.checkThreadLocalMapForLeaks网络应用[/core-1.0.0-RC2]创建了一个ThreadLocal,其密钥类型为[ org.apache.log4j.helpers.ThreadLocalMap](值[org.apache.log4j.helpers.ThreadLocalMap@464437fc])和类型为[java.util.Hashtable]的值(值[{siteCode = 000tst,transactionId = dc8f3a1b- 1d7a-4f91-abf6-58d015632d03}]),但在停止Web应用程序时无法将其删除。线程将随着时间的流逝而更新,以尝试避免可能的内存泄漏。

我有一个其中MDC称为RequestFilter:

import org.slf4j.MDC;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import java.io.IOException;
import java.util.UUID;

public void filter(ContainerRequestContext containerRequestContext) throws IOException {

    String siteCodeHeader = containerRequestContext.getHeaderString("Site-Code");

    if (siteCodeHeader != null) {
        MDC.put("siteCode", siteCodeHeader);
    } else {
        MDC.put("siteCode", "NULL");
    }
    MDC.put("transactionId", UUID.randomUUID().toString());


}


这些是我的sl4fj依赖项:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.7</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.7</version>
</dependency>


如果我具有带有MDC.clear()的ResponseFilter,它将从MDC中删除值,但似乎并未清除线程:

2014年9月27日09:12:58.216严重[localhost-startStop-2] org.apache.catalina.loader.WebappClassLoader.checkThreadLocalMapForLeaks网络应用[/core-1.0.0-RC2]创建了一个ThreadLocal,其密钥类型为[ org.apache.log4j.helpers.ThreadLocalMap](值[org.apache.log4j.helpers.ThreadLocalMap@391216c7])和类型为[java.util.Hashtable]的值(值[{}]),但未能将其删除当Web应用程序停止时。线程将随着时间的流逝而更新,以尝试避免可能的内存泄漏。

显然,它已在log4j 1.2.17中修复,但是更改似乎并未过滤到slf4j。

最佳答案

使用ThreadLocal将MDC保留在当前线程中。如果在过滤器中添加值,则必须在服务呼叫后将其删除。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
   try
   {

     //add your mdcs

     // proceed along the chain
     chain.doFilter(request, response);

  }
  finally
  {

     //remove your mdcs

  }
}

关于java - SLF4J MDC内存泄漏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26075283/

10-10 07:43