gpt4 book ai didi

java - SLF4J MDC 内存泄漏

转载 作者:行者123 更新时间:2023-11-30 09:02:15 28 4
gpt4 key购买 nike

我为此搜索了谷歌,查看了多项建议,但似乎无济于事。

我有一个使用 MDC 的 JAX-RS 应用程序,当一个端点被命中时设置一个 transactionId 以使调试更容易。但是,当我停止或重新启动 Tomcat 时,日志中充满了如下条目:

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

我有一个 RequestFilter,其中调用了 MDC:

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 Web 应用程序 [/core-1.0.0-RC2] 使用 key 创建了一个 ThreadLocal [org.apache.log4j.helpers.ThreadLocalMap] 类型(值 [org.apache.log4j.helpers.ThreadLocalMap@391216c7])和 [java.util.Hashtable] 类型的值(值 [{}])但失败在 Web 应用程序停止时删除它。线程将随着时间的推移而更新,以尝试避免可能的内存泄漏。

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

最佳答案

结合使用前两个答案,我能够解决问题。

我使用了 MDC 的 log4j 实现而不是 SLF4J,并且还添加了一个 ResponseFilter 来进行清除。它可能会影响它,也可能不会影响它,但我还使用了提供者注释,而不是在 web.xml 中规定类。

RequestFilter(大致相同):

package com.example.jaxrs;

import org.apache.log4j.MDC;

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

@Provider
public class TransactionIdentifierRequestFilter implements ContainerRequestFilter {

@Override
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());

}
}

响应过滤器:

package com.example.jaxrs;

import org.apache.log4j.MDC;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;

@Provider
public class TransactionIdentifierResponseFilter implements ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) throws IOException {
MDC.clear();
}
}

网络.xml

<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.example.jaxrs</param-value>
</init-param>

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

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