Question
Why does Spring's RestTemplate use an excessive amount of heap (particularly the G1 Old Generation
) when sending a file.
Context
We observed the RestTemplate to consume excessive amounts of memory when sending files via POST
requests. We used Spring's WebClient as comparison and it behaves completely sane.
We created a demo project on github which contains the full code. The important parts are the following snippets:
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);
}
and
private void sendFileAsOctetStream(File file) {
webClient.post()
.uri("/file")
.body(BodyInserters.fromResource(new FileSystemResource(file)))
.exchange()
.block();
}
We observed the memory usage with jconsole
when sending a 550MB file with both the implementations (left is WebClient
, right is RestTemplate
. The WebClient
cosumes a couple of MegaBytes while the RestTemplate
requires 2.7 GigaByte:
- An initial manual GC to clean the old generation
- The request
- A manual GC (only for the
RestTemplate
)