java - 关闭 Java HTTP 客户端
问题描述
有没有办法关闭java.net.http.HttpClient
立即释放它所持有的资源?
在内部,它包含一个选择器、一个连接池和一个Executor
(使用默认值时)。但是它没有实现Closeable
/ AutoCloseable
。
解决方案
当我将war文件重新部署到Tomcat中时,我遇到了类似的问题。War 应用程序有一个 HttpClient,它正在运行发出 http 请求和处理结果的预定作业。
我经常在开发环境中重新部署战争文件时看到来自 Tomcat 的警告,即挂起可能导致内存泄漏的线程。堆栈跟踪指向 HttpClient 线程。经过几次尝试,我以这种方式解决了这个问题:
HttpClient 仅在需要执行作业时创建。它不是作为类或服务的字段创建的,而是作为调度方法内的局部变量创建的。
HttpClient 是使用 builder 创建的,并使用 ThreadPool Executor 填充,因此我保留到 Executor 的链接并对其进行控制。
ExecutorService executor = Executors.newSingleThreadExecutor(); HttpClient client = HttpClient.newBuilder().followRedirects(Redirect.ALWAYS).connectTimeout(Duration.ofSeconds(5)).executor(executor).build();
当工作在 try-catch 块中完成时,finally 部分有这两行:显式关闭线程池并将 null 设置为 httpClient 局部变量:
executor.shutdownNow(); client = null; System.gc();
注意,连接超时时间短以限制执行时间。保持少量线程。我使用 1 个线程的线程池。
在所有这些更改之后,有关内存泄漏的警告从 Tomcat 日志中消失了。
推荐阅读
- sql - SQL 没有这个函数 YEAR
- sorting - 是否可以以简单的方式对 groupBy 中的每个组进行排序?
- npm - expo start 在命令行中通过 Exit status 1 在@start 脚本中失败
- python - csv的伪代码转换成python
- python - 在 Pandas 中替换列表类型列中的重复项
- python - 如何在 Kivy 的滚动视图顶部创建一个固定按钮?
- python - 使用条件语句将值映射到分隔 col:python
- javascript - 如何计算 HTML 字符串中的所有图像标签?
- javascript - 如何从父对象列表中删除子对象javascript
- api - 为什么电源自动化自定义连接器为不同的请求 URL 返回相同的结果?