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.

Cognitive Technology Team
Cognitive Technology Team
Cognitive Technology Team
Why Spring WebClient Throws OutOfMemoryError and How to Fix It

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.

yCrash event summary report
yCrash event summary report

Garbage Collection Analysis

The yCrash GC report shows consecutive Full GC cycles, which pause the entire application and lead to unresponsiveness before the OutOfMemoryError.

Full GC issue
Full GC issue

Log Analysis Highlights Direct Buffer OOM

The yCrash log analysis pinpoints the java.lang.OutOfMemoryError: Direct buffer memory as the crash cause.

Log report showing OutOfMemoryError
Log report showing OutOfMemoryError

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.

Spring BootresttemplatewebclientdiagnosticsJava NIOOutOfMemoryError
Cognitive Technology Team
Written by

Cognitive Technology Team

Cognitive Technology Team regularly delivers the latest IT news, original content, programming tutorials and experience sharing, with daily perks awaiting you.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.