Why Spring WebClient Throws OutOfMemoryError and How to Fix It
Upgrading Spring Boot's RestTemplate to the NIO‑based WebClient improves concurrency and performance, but can trigger a java.lang.OutOfMemoryError: Direct buffer memory; this article explains the cause, diagnostic steps using yCrash, and how adjusting -XX:MaxDirectMemorySize resolves the issue.
Spring Boot is a popular Java framework for enterprise applications, and integrating with external services via HTTP REST is common. Upgrading from RestTemplate to the NIO‑based WebClient can improve performance and concurrency.
WebClient advantages include:
Concurrency : handles multiple connections without blocking threads.
Asynchrony : allows other tasks while waiting for I/O.
Performance : non‑blocking I/O uses fewer threads for more connections.
However, using the same number of concurrent connections, WebClient can encounter an OutOfMemoryError due to direct buffer memory exhaustion.
Spring RestTemplate
public void restClientCall(Integer id, String url,String imagePath) { // Create RestTemplate instance
RestTemplate restTemplate = new RestTemplate(); // Prepare image file
File imageFile = new File(imagePath); // Prepare headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA); // Prepare request body
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", new org.springframework.core.io.FileSystemResource(imageFile)); // Create HTTP entity with headers and body
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
System.out.println("Starting to post an image for Id"+id);
// Execute POST request
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, requestEntity, String.class);
System.out.println("Response Id "+id +":"+ responseEntity.getBody());
System.out.println(" Time: " + LocalTime.now());
}Spring WebClient
public void webHeavyClientCall(Integer id,String url, String imagePath) { // Create WebClient instance
WebClient webClient = WebClient.create(); // Prepare image file
File imageFile = new File(imagePath); // Prepare request body
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", new FileSystemResource(imageFile));
System.out.println("Image upload started "+id);
webClient.post().uri(url).contentType(MediaType.MULTIPART_FORM_DATA).body(BodyInserters.fromMultipartData(body)).retrieve().bodyToMono(String.class).subscribe(response -> {
System.out.println("Response Id"+id+ ":" + response);
});
}WebClient triggers OutOfMemoryError
Running both programs on OpenJDK 11, the WebClient version fails after a few iterations with java.lang.OutOfMemoryError: Direct buffer memory, while the RestTemplate version runs successfully.
Starting to post an image for Id0
...
2023-12-06 17:21:46.730 WARN 13804 --- [tor-http-nio-12] io.netty.util.concurrent.DefaultPromise : An exception was thrown by reactor.ipc.netty.FutureMono$FutureSubscription.operationComplete()
reactor.core.Exceptions$ErrorCallbackNotImplemented: io.netty.channel.socket.ChannelOutputShutdownException: Channel output shutdown
Caused by: java.lang.OutOfMemoryError: Direct buffer memory
at java.base/java.nio.Bits.reserveMemory(Bits.java:175)
...Diagnosing the Direct Buffer Memory Issue
We used the yCrash monitoring tool to capture comprehensive artifacts (GC logs, thread dumps, heap snapshots, netstat, vmstat, iostat, top, dmesg, kernel parameters, disk usage, etc.) before the failure occurred.
Garbage Collection Analysis
The yCrash GC report shows consecutive Full GC cycles, which pause the entire application and lead to unresponsiveness before the OutOfMemoryError.
Log Analysis Highlights Direct Buffer OOM
The yCrash log analysis pinpoints the java.lang.OutOfMemoryError: Direct buffer memory as the crash cause.
Why WebClient Consumes Direct Memory
Spring WebClient is built on Java NIO, storing objects in the JVM's "direct buffer memory" region, whereas RestTemplate stores objects in other native memory areas. When the direct memory size is limited (e.g., -XX:MaxDirectMemorySize=200k), WebClient exhausts it, causing the OOM error.
Increasing -XX:MaxDirectMemorySize
By raising the JVM parameter to -XX:MaxDirectMemorySize=1000k, the WebClient runs normally without errors.
Starting to post an image for Id0
...
Response Id19:Image uploaded successfully!Conclusion
This article examined the OutOfMemoryError encountered when upgrading from Spring RestTemplate to the NIO‑based WebClient, presented diagnostic steps using yCrash, and demonstrated that increasing the direct memory limit resolves the issue.
Cognitive Technology Team
Cognitive Technology Team regularly delivers the latest IT news, original content, programming tutorials and experience sharing, with daily perks awaiting you.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
