为什么RestTemplate会消耗过多的内存?

Trinova:

为什么Spring的RestTemplate G1 Old Generation在发送文件时会使用过多的堆(尤其是)。

语境

通过请求发送文件时,我们观察到RestTemplate消耗过多的内存POST我们使用Spring的WebClient作为比较,它的行为完全健全。

我们在github上创建了一个演示项目,其中包含完整的代码。重要的部分是以下片段:

private void sendFileAsOctetStream(File file) {
    final RequestEntity<FileSystemResource> request = RequestEntity.post(URI.create("http://localhost:8080/file"))
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .body(new FileSystemResource(file));
    restTemplate.exchange(request, void.class);
}

private void sendFileAsOctetStream(File file) {
    webClient.post()
            .uri("/file")
            .body(BodyInserters.fromResource(new FileSystemResource(file)))
            .exchange()
            .block();
}

我们在jconsole两种实现中都发送550MB文件时观察到内存使用情况(左为WebClient,右为RestTemplateWebClient总共消耗了2 兆字节,而RestTemplate需要2.7 千兆字节

在此处输入图片说明

  1. 最初的手动GC可以清理旧一代
  2. 要求
  3. 手动GC(仅适用于RestTemplate
Lino-投票不要说谢谢:

这是由于默认设置RestTemplate该默认设置仅使用未配置SimpleClientHttpRequestFactory的请求创建。

提到的requst工厂具有一个标志bufferRequestBody,默认情况下将其设置为true,这会在发送大请求时导致很高的内存消耗。

来自的javadoc SimpleClientHttpRequestFactory#setBufferRequestBody()

指示此请求工厂是否应在内部缓冲请求主体。默认为true。通过POST或PUT发送大量数据时,建议将此属性更改为false,以免耗尽内存这将导致ClientHttpRequest要么直接流到基础HttpURLConnection(如果预先知道Content-Length),要么将使用“块传输编码”(如果预先不知道Content-Length)。

RestTemplate使用其他重载的构造函数之一创建,并false在请求工厂上将提到的标志设置为时,您可以提供自己的请求工厂:

@Bean
public RestTemplate restTemplate() {
    SimpleClientHttpRequestFactory rf = new SimpleClientHttpRequestFactory();
    rf.setBufferRequestBody(false);
    return new RestTemplate(rf);
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么MySQL会消耗大量内存?

为什么简单的Go应用会消耗大量内存

为什么创建一个大型Java阵列会消耗大量内存?

为什么一个空的Java程序会消耗内存?

为什么在Atlas中添加纹理不会降低内存消耗?

为什么内存消耗增加而不是减少并保持不变

为什么JVM消耗的内存少于指定的-Xms?

多处理队列-为什么内存消耗增加?

为什么 free 命令说的与实际消耗的内存不同

为什么在闲置时ubuntu会消耗25%的CPU?

为什么我在Linux上的服务会消耗大量CPU?

为什么数组范围原语会消耗其源?

为什么STRAIGHT_JOIN会消耗更多的CPU?

为什么Google在Firefox中的搜索结果会消耗CPU?

为什么虚拟循环会消耗内核时间?

为什么“ grep -q”会消耗整个输入文件?

为什么 FnMut 闭包会消耗捕获的变量?

为什么 Devel::LeakTrace 会泄漏内存?

装饰器会消耗更多的内存吗?

枚举常量标签会消耗内存吗?

为单个标签赋予颜色会消耗过多的处理能力

无限的“ while循环”会消耗过多的资源吗?

USB端口(或母板)是否会因消耗过多功率而损坏?

为什么 mmap 标志减少了单个 Word2Vec 实例的内存消耗

在V8中,为什么预分配的阵列消耗的内存更少?

为什么这个简单的 GTK3 应用程序消耗这么多内存?

为什么这个简单的Shell循环停顿并开始消耗大量内存?

即使堆等大小稳定,为什么Sun JVM仍继续消耗更多的RSS内存?

运行时-为什么freeMemory()无法正确显示内存消耗?