当前位置: 首页 > 知识库问答 >
问题:

SLF4J MDC内存泄漏

狄兴业
2023-03-14

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

27-SEP-2014 09:42:14.858严重的[localhost-startStop-2]org.apache.catalina.loader.webappclassloader.checkThreadLocalMapforLeaks web应用程序[/core-1.0.0-rc2]创建了一个ThreadLocal,其键类型为[org.apache.log4j.helpers.ThreadLocalMap](值[org.apache.log4j.helpers.ThreadLocalMap@464437fc])和值类型为[java.util.Hashtable](值[{sitecode=000tst,15632D03}])但在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.ranhtml" target="_blank">domUUID().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中删除值,但似乎不会清除线程:

27-SEP-201409:12:58.216严重的[localhost-startStop-2]org.apache.catalina.loader.webappclassloader.checkThreadLocalMapforLeaks web应用程序[/core-1.0.0-rc2]创建了一个ThreadLocal,其键类型为[org.apache.log4j.helpers.ThreadLocalMap](值[org.apache.log4j.helpers.ThreadLocalMap@391216C7])和值类型为[java.util.hashtable](值[{}]),但在web应用程序停止时线程将随着时间的推移而更新,以避免可能的内存泄漏。

显然,它在log4j1.2.17中得到了修复,但这些变化似乎并没有渗透到slf4j中。

共有1个答案

江凯风
2023-03-14

使用前面两个答案的混合,我能够解决这个问题。

我使用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();
    }
}
<init-param>
    <param-name>jersey.config.server.provider.packages</param-name>
    <param-value>com.example.jaxrs</param-value>
</init-param>
 类似资料:
  • 问题内容: 我认为我的android应用正在泄漏内存。我不是绝对确定这是问题所在。 应用程序打开时经常崩溃,并且logcat尝试加载位图图像时会显示“内存不足”异常。 崩溃后,我重新打开了该应用程序,它运行正常。Logcat会显示许多“ gc”,并且JIT表会不时地向上调整大小,而不会向下调整,直到应用程序因内存不足错误而崩溃。 这听起来像是内存泄漏吗?如果是这样,我该如何定位和关闭泄漏点。 这是

  • 问题内容: 我一直在追寻内存泄漏(由“ valgrind –leak-check = yes”报告),它似乎来自ALSA。这段代码已经存在于自由世界中一段时间​​了,所以我猜这是我做错的事情。 输出看起来像这样: 并继续一些页面 这是由于我在一个项目中使用ALSA并开始看到这种巨大的泄漏……或者至少是所说泄漏的报告。 所以问题是:是我,ALSA或valgrind在这里遇到问题吗? 问题答案: ht

  • 问题内容: 我有一个长时间运行的脚本,如果让脚本运行足够长的时间,它将消耗系统上的所有内存。 在不详细介绍脚本的情况下,我有两个问题: 是否有可遵循的“最佳实践”,以防止泄漏发生? 有什么技术可以调试Python中的内存泄漏? 问题答案: 看看这篇文章:跟踪python内存泄漏 另外,请注意,垃圾收集模块实际上可以设置调试标志。看一下功能。此外,请查看Gnibbler的这段代码,以确定调用后已创建

  • 本文向大家介绍Java 内存泄漏,包括了Java 内存泄漏的使用技巧和注意事项,需要的朋友参考一下 在Java中,垃圾回收(析构函数的工作)是使用垃圾回收自动完成的。但是,如果代码中有引用它们的对象怎么办?它无法取消分配,即无法清除其内存。如果这种情况一再发生,并且创建或引用的对象根本没有被使用,它们就会变得无用。这就是所谓的内存泄漏。 如果超过了内存限制,则程序将通过抛出错误(即“ OutOfM

  • 问题内容: 我使用Informix遇到了一个奇怪的问题(具体来说,我使用的是IBM.Data.Informix命名空间,即4.10 Client SDK)。我正在使用ODBC连接到IBM Informix数据库,并且遇到内存泄漏问题。该文档相当稀疏,并且我只能使用当前安装的驱动程序/ SDK。这是我用于数据库上下文的代码: } 我已尝试处置并关闭所有可以的连接,但这似乎无济于事。我是否缺少某些东西

  • 我们有一个基于go-socket.io(socket.ioGo语言实现)和大猩猩网络插座的网络插座服务,但是似乎有内存泄漏问题。即使我使用调试,HeapAlloc也总是在增加。FreeOSMemroy强制释放内存。 服务很简单。它将使用jwt令牌对传入请求进行身份验证,如果身份验证成功,则将创建一个go套接字。io conn基于gorilla websocket conn。但现在似乎是net/te

  • 问题内容: 我发现使用是众所周知的与相关的内存问题。 使用中是否存在内存泄漏? 如果是,解决方法是什么? 以下链接显示了Java中子字符串的正确用法。 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4513622 另外一个博客谈论子字符串中可能的MLK。 http://nflath.com/2009/07/the-dangers-of- st

  • 我有一个这样的静态ExpressJS服务器: 当我启动服务器时,它使用20MB的v8堆。如果我每秒重新加载一个页面,则使用的堆会不断增长。4小时后,使用的v8堆将达到40MB。v8堆的总容量达到80MB,RSS(进程使用的总内存)达到130MB。 为什么这个简单而静态的服务器使用这么多内存?这似乎是内存泄漏。如果我不停止页面重新加载,使用的内存会继续增长。 如果像这样一个简单的静态服务器使用了太多