You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HttpClient 5.2.1版本HTTP/2通信下内存占用与GC性能问题

HttpClient 5.2.1版本HTTP/2通信内存泄漏问题排查求助

我们将用于HTTP/2通信的HttpClient库从5.1版本升级至5.2.1版本后,遇到严重内存异常:连接ALB(应用负载均衡器)暴露的任意端点时,应用内存占用过高且无法高效释放,导致垃圾回收(GC)耗时显著增加。

问题复现情况

  • 已提供可运行的示例应用,仅发送100次请求即可观察到内存占用快速上升
  • 相同代码切换为HTTP/1.1协议时运行完全正常
  • 示例应用内存配置:-Xms64m -Xmx512m

内存占用对比

HTTP/1.1下内存占用

HTTP/1.1内存占用

HTTP/2下内存占用

HTTP/2内存占用

示例代码

package org.example;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
import org.apache.hc.client5.http.async.methods.SimpleResponseConsumer;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.config.TlsConfig;
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.core5.concurrent.FutureCallback;
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.util.Timeout;

public class App 
{
    public static void main( String[] args ) throws InterruptedException, IOException {
        CloseableHttpAsyncClient client = provideHttpAsyncClient();
        client.start();
        ExecutorService executors = Executors.newFixedThreadPool(8);
        final CountDownLatch countDownLatch = new CountDownLatch(100);
        for(int i=0; i< 100; i++) {
            executors.submit(() -> {
                try {
                    Thread.sleep(500);
                  client.execute(new BasicRequestProducer("GET", new URI("https://www.figma.com/")),
                      SimpleResponseConsumer.create(),null, HttpClientContext.create(),
                      new FutureCallback<>() {
                        @Override
                        public void completed(SimpleHttpResponse result) {
                          System.out.println(result.getCode() + " " + result.getVersion());
                          countDownLatch.countDown();
                          System.out.println("Current heap size " + Runtime.getRuntime().totalMemory()/1000000 + "MB");
                        }

                        @Override
                        public void failed(Exception ex) {
                          System.out.println("Something went wrong... " + ex);
                          countDownLatch.countDown();
                        }

                        @Override
                        public void cancelled() {
                          System.out.println("cancelled");
                          countDownLatch.countDown();
                        }
                      }
                  );
                } catch (InterruptedException | URISyntaxException e) {
                    throw new RuntimeException(e);
                }
            });
        }
        countDownLatch.await();
        client.close();
        System.out.println("Client closed");
    }

    public static CloseableHttpAsyncClient provideHttpAsyncClient() {
        RequestConfig requestConfig = getRequestConfig();
        PoolingAsyncClientConnectionManagerBuilder connectionManagerBuilder =
            PoolingAsyncClientConnectionManagerBuilder.create()
                .setMaxConnPerRoute(100)
                .setMaxConnTotal(30)
                .setDefaultTlsConfig(prepareTLSConfig());

        PoolingAsyncClientConnectionManager connManager = connectionManagerBuilder.build();

        IOReactorConfig ioReactorConfig =
            IOReactorConfig.custom()
                .setSoTimeout(60, TimeUnit.SECONDS)
                .build();

      return HttpAsyncClients.custom()
          .setDefaultRequestConfig(requestConfig)
          .setIOReactorConfig(ioReactorConfig)
          .setConnectionManager(connManager)
          .build();
    }

    static private TlsConfig prepareTLSConfig() {
        HttpVersionPolicy httpVersionPolicy =
            HttpVersionPolicy.FORCE_HTTP_1;
        return new TlsConfig.Builder().setVersionPolicy(httpVersionPolicy).build();
    }
    static RequestConfig getRequestConfig() {
        RequestConfig.Builder builder =
            RequestConfig.custom()
                .setResponseTimeout(
                    Timeout.ofSeconds(
                        15)) // Timeout until a new connection is fully
                // established
                .setConnectionRequestTimeout(Timeout.ofSeconds(60))
                .setResponseTimeout(Timeout.ofSeconds(60));
        return builder.build();
    }
}

我们尝试使用OkHTTP库执行相同操作,运行情况完全正常。恳请协助定位问题原因并提供可行的解决方案。

内容的提问来源于stack exchange,提问作者Sandeep Gaur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 07:04:57