首页 > 解决方案 > 关闭 Java HTTP 客户端

问题描述

有没有办法关闭java.net.http.HttpClient立即释放它所持有的资源?

在内部,它包含一个选择器、一个连接池和一个Executor(使用默认值时)。但是它没有实现Closeable/ AutoCloseable

标签: javajava-11java-http-client

解决方案


当我将war文件重新部署到Tomcat中时,我遇到了类似的问题。War 应用程序有一个 HttpClient,它正在运行发出 http 请求和处理结果的预定作业。

我经常在开发环境中重新部署战争文件时看到来自 Tomcat 的警告,即挂起可能导致内存泄漏的线程。堆栈跟踪指向 HttpClient 线程。经过几次尝试,我以这种方式解决了这个问题:

  1. HttpClient 仅在需要执行作业时创建。它不是作为类或服务的字段创建的,而是作为调度方法内的局部变量创建的。

  2. HttpClient 是使用 builder 创建的,并使用 ThreadPool Executor 填充,因此我保留到 Executor 的链接并对其进行控制。 ExecutorService executor = Executors.newSingleThreadExecutor(); HttpClient client = HttpClient.newBuilder().followRedirects(Redirect.ALWAYS).connectTimeout(Duration.ofSeconds(5)).executor(executor).build();

  3. 当工作在 try-catch 块中完成时,finally 部分有这两行:显式关闭线程池并将 null 设置为 httpClient 局部变量: executor.shutdownNow(); client = null; System.gc();

注意,连接超时时间短以限制执行时间。保持少量线程。我使用 1 个线程的线程池。

在所有这些更改之后,有关内存泄漏的警告从 Tomcat 日志中消失了。


推荐阅读