在Tomcat中使用net.http.HttpClient会导致内存泄漏

问题描述

我正在基于Servlet的Web应用程序中使用Java的新版本(版本11起)HttpClient

private static final HttpClient HTTP_CLIENT =
  .connectTimeout(Duration.ofSeconds(5))
  .followRedirects(HttpClient.Redirect.NORMAL)
  .build();

...

public void httpPostAsyncToEndpoint(WebEndpoint endpoint,Map<String,String> params) {
  HttpRequest req = buildRequest(endpoint,params);
  CompletableFuture<HttpResponse<String>> future = HTTP_CLIENT.sendAsync(req,HttpResponse.BodyHandlers.ofString());
  future.thenAccept((HttpResponse<String> res) -> {
    if (res.statusCode() >= 400) {
      if (LOGGER.isErrorEnabled()) {
        LOGGER.error("{} HTTP response returned from endpoint {}",endpoint,res.statusCode());
      }
    }
  }).exceptionally(ex -> {
    if (LOGGER.isErrorEnabled()) {
      LOGGER.error("Could not audit event using endpoint {}",ex);
    }
    return null;
  });
}

一切正常,但是在Tomcat上重新启动Web应用程序时,会产生以下警告:

14-Aug-2020 09:21:16.996 WARNING [http-nio-8080-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [MyApp] appears to have started a thread named [HttpClient-3-SelectorManager] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 java.base/sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
 java.base/sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:357)
 java.base/sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:182)
 java.base/sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:124)
 java.base/sun.nio.ch.SelectorImpl.select(SelectorImpl.java:136)
 java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.run(HttpClientImpl.java:867)

如何防止这种情况?我试图使用一个自定义ThreadFactory,它仅返回守护程序线程:

HttpClient.newBuilder()
  .executor(Executors.newSingleThreadExecutor((Runnable r) -> {
    Thread t = new Thread(r);
    t.setDaemon(true);
    return t;
  }))
  .connectTimeout(Duration.ofSeconds(5))
  .followRedirects(HttpClient.Redirect.NORMAL).build();

但警告仍然存在。

我正在Tomcat 9上使用OpenJDK 11.0.7。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)