gpt4 book ai didi

java - Apache Avro ThreadLocal 对象在 Tomcat 未部署时徘徊

转载 作者:搜寻专家 更新时间:2023-11-01 03:53:58 26 4
gpt4 key购买 nike

我们使用 Apache Avro 作为我们的 Python 应用程序和我们在 Tomcat 服务中运行的一些第三方 Java 库之间的 JSON 接口(interface)。我们决定简单地扩展 org.apache.avro.ipc.ResponderServlet 类来实现我们自己的 servlet。 servlet 非常简单,因为它在构造函数中实例化 ResponderServlet 父类(super class),并覆盖 init() 和 destroy() 方法来为我们在 servlet 中运行的第三方库做一些内务处理。

然而,当 Tomcat 取消部署我们的 web 应用程序时,我们看到许多警告 ThreadLocal 相关内存泄漏的严重错误。

SEVERE: The web application [/hotwire] created a ThreadLocal with key of type [org.apache.avro.Schema$3] (value [org.apache.avro.Schema$3@4464784f]) and a value of type [java.lang.Boolean] (value [true]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
Jan 24, 2013 2:19:36 AM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/hotwire] created a ThreadLocal with key of type [org.apache.avro.generic.GenericDatumReader$1] (value [org.apache.avro.generic.GenericDatumReader$1@2016ad9d]) and a value of type [org.apache.avro.util.WeakIdentityHashMap] (value [org.apache.avro.util.WeakIdentityHashMap@30e02ee0]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

我们可能在某个地方做了一些幼稚的事情,因为我们无法在网络上的任何地方找到任何关于这种情况的帮助。尽管如此,我们还是希望有人能告诉我们哪里出了问题。

下面是我们的 servlet 的一瞥。

public class HotWire extends ResponderServlet{
public HotWire() throws IOException
{
super(new SpecificResponder(Engine.class, new EngineImpl()));
}

@Override
public void init() {
try {
super.init();
try {
init_engine();
} catch (EngineInitException e) {
e.printStackTrace();
}
} catch (ServletException e) {
e.printStackTrace();
}
}

@Override
public void destroy() {
super.destroy();
shutdown_engine();
}

public static class EngineImpl implements EngineInterface {
public Boolean create(Parameters message) {
Boolean status = null;
try {
status = engine.create_object(message);
} catch (SemanticException | IOException e) {
e.printStackTrace();
}
return status;
}

}

最佳答案

我遇到了类似的问题。如果你看这里有一个静态的 ThreadLocal 缓存,它被填满而无法删除它:

https://github.com/apache/avro/blob/master/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java#L106

  private static final ThreadLocal<Map<Schema, Map<Schema, ResolvingDecoder>>> RESOLVER_CACHE = ThreadLocal
.withInitial(WeakIdentityHashMap::new);

在我的例子中,每个请求都有不同的模式,因此我的 Spring Boot 服务最终会耗尽内存并终止。

这也是一个类加载器泄漏的例子: ThreadLocal & Memory Leak

我可以在这里看到一个 JIRA 请求改进: https://issues.apache.org/jira/browse/AVRO-1595

更新:我能够解决内存泄漏问题。有一个 ExecutorService 正在重用线程。现在我关闭了导致线程完成的服务。这允许对 ThreadLocal 内存进行 GC。

正如有人指出的那样,RESOLVER_CACHE 使用了一个 WeakIdentityHashMap,它应该允许对缓存进行 GC,但这对我来说并没有发生。

关于java - Apache Avro ThreadLocal 对象在 Tomcat 未部署时徘徊,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14522161/

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