java - Apache HttpAsyncClient 内存泄漏

标签 java memory-leaks garbage-collection apache-httpclient-4.x apache-httpasyncclient

我需要在高负载下使用HttpAsyncClient。我像这样创建 HttpAsyncClient:

RequestConfig requestConfig = RequestConfig.custom()
        .setConnectTimeout(CONNECT_TIMEOUT)
        .setSocketTimeout(SOCKET_TIMEOUT)
        .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
        .build();
HttpAsyncClient client = HttpAsyncClients.custom()
        .setDefaultRequestConfig(createRequestConfig())
        .build();

然后我这样使用它:

HttpPost request = new HttpPost(url);
request.setEntity(new StringEntity(requestBody, "UTF-8"));
client.execute(request, null)

通常我并不真正关心响应,所以我不初始化 Future<HttpResponse>变量并且不执行 Future.get() 。好吧,只是为了澄清(我不认为这与问题有关),我有时关心回复,但 99% 的回复对我来说并不有趣。

问题是当我执行大量请求时(例如每秒 300 个请求,这里的“请求”一词是指 client.execute() 调用)我最终得到 java.lang.OutOfMemoryError: GC overhead limit exceeded 。我尝试使用 VisualVM 来了解发生了什么。我看到java.lang.Object[] , char[] , java.lang.String , byte[] , short , char[]实例数正在增长(我尝试强制 GC 并限制堆大小以确保它不正常 - 没有帮助)。已用堆空间的增长也是如此。

什么原因导致这个问题?也许我应该使用 HttpAsyncClient一些不同的方式?我需要使用自定义RequestProducer , ResponseProducer或使用CountDownLatch

UPD 问题是因为 PowerMock 库

最佳答案

HttpAsyncClient 不会以任何方式或方式限制请求执行速率,以避免阻塞 #execute 方法。人们可以向客户端提交无限数量的请求,客户端会尽职尽责地将它们全部放入执行队列中。这些请求实际执行和从队列中删除的速度是一个完全不同的故事,并且可能取决于许多因素。在您的特定情况下,您尝试每条路由仅使用 2 个并发连接来处理所有这些请求,这可能不一定是最佳做法。

PS:/老人的提示/人们不应该认为异步客户端会因为某种原因更快。除非用于特定用例并以特定方式使用,否则它们不会被使用。可以肯定的是,除非非常小心,否则异步客户端很容易最终会使用更多内存。

关于java - Apache HttpAsyncClient 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34811632/

相关文章:

java - java中向Hashmap中插入字符。HashMap中字符的顺序与输入顺序不同

java - 在 tomcat 服务器中运行的 J2ee 线程

java - 将本地机器名放入 mySQL 表中

ios - Core Graphics cocoa 内存泄漏

.net - 过多的 Gen 2 集合

java - 为什么我会使用 list.clear()

java - 如何避免此 java 代码的额外输出

.net - 诊断.NET中的内存泄漏的工具(ASP.NET应用程序)

android - java.lang.OutOfMemory错误: bitmap size exceeds VM budget - Android

java - 为什么使用 Epsilon 与 G1 相比,观察到重复的内存分配更慢?