There are 9 types of java.lang.OutOfMemoryError, each signaling a unique memory-related issue within Java applications. Among these, ‘java.lang.OutOfMemoryError: Direct buffer memory’ is starting to appear in modern JVMs and Spring Boot framework. In this post, we’ll delve into the root causes behind this error, explore potential solutions, and discuss effective diagnostic methods to troubleshoot this problem. Let’s equip ourselves with the knowledge and tools to conquer this common adversary.
Here’s a video summary of the article:
JVM Memory Regions
To better understand OutOfMemoryError, we first need to understand different JVM Memory regions. Here is a video clip that gives a good introduction about different JVM memory regions. But in nutshell, JVM has following memory regions:

- Young Generation: Newly created application objects are stored in this region.
- Old Generation: Application objects that are living for longer duration are promoted from the Young Generation to the Old Generation. Basically this region holds long lived objects.
- Metaspace: Class definitions, method definitions and other metadata that are required to execute your program are stored in the Metaspace region. This region was added in Java 8. Before that metadata definitions were stored in the PermGen. Since Java 8, PermGen was replaced by Metaspace.
- Threads: Each application thread requires a thread stack. Space allocated for thread stacks, which contain method call information and local variables are stored in this region.
- Code Cache: Memory areas where compiled native code (machine code) of methods is stored for efficient execution are stored in this region.
- Direct Buffer: ByteBuffer objects are used by modern framework (i.e. Spring WebClient) for efficient I/O operations. They are stored in this region.
- GC (Garbage Collection): Memory required for automatic garbage collection to work is stored in this region.
- JNI (Java Native Interface): Memory for interacting with native libraries and code written in other languages are stored in this region.
- misc: There are areas specific to certain JVM implementations or configurations, such as the internal JVM structures or reserved memory spaces, they are classified as ‘misc’ region.
What is ‘java.lang.OutOfMemoryError: Direct buffer memory’?

When lot of objects are created in direct buffer region, than the allocated direct buffer memory limit, (i.e., ‘-XX:MaxDirectMemorySize’), JVM will throw ‘java.lang.OutOfMemoryError: Direct buffer memory’.
What causes ‘java.lang.OutOfMemoryError: Direct buffer memory’?
‘java.lang.OutOfMemoryError: Direct buffer memory’ is triggered by the JVM under following circumstances:
- Memory Leak due to Buggy code: If your application is not properly releasing direct buffers after use, they can accumulate over time and eventually exhaust the available direct buffer memory.
- High Rate of Allocation: If your application is allocating direct buffers at a very high rate and not releasing them promptly, it can quickly consume the available memory.
- Switching from Spring RestTemplate to WebClient: Spring Boot is a popular framework for Java enterprise applications. One common method of integration with internal or external applications is through RestTemplate APIs. Modern versions of Spring advocate to use Java NIO-based WebClient for better performance. While NIO based Webclient delivers better performance, it shifts the objects creation from the heap memory region to the Direct Buffer region. Thus when you make this shift, it will result in memory pressures in the Direct Buffer region.
Solutions for ‘OutOfMemoryError: Direct buffer memory’
Following are the potential solutions to fix this error:
- Fix Memory Leak: Analyze memory leak in the Direct Buffer memory region, ensure that objects are properly dereferenced when they are no longer needed to allow them to be garbage collected.
- Increase Direct Buffer size: If OutOfMemoryError surfaced due the increase in the traffic volume, then increase the JVM’s Direct Buffer Memory region size (-XX:MaxDirectMemorySize).
- Upgrade to Java 17 (or above version): Enhancements have been made in Java 17 to use the Direct Buffer Memory region in an effective manner. Thus, if you happen to be running on a version less than Java 17, upgrade it. Here is a case study that showcases the performance optimization to Direct Buffer Memory region in Java 17.
Sample Program that generates ‘OutOfMemoryError: Direct buffer memory’
To better understand ‘java.lang.OutOfMemoryError: Direct buffer memory’, let’s try to simulate it. Let’s leverage BuggyApp, a simple open-source chaos engineering project. BuggyApp can generate various sorts of performance problems such as Memory Leak, Thread Leak, Deadlock, multiple BLOCKED threads, … Below is the program from the BuggyApp project that attempts to create a very large ByteBuffer, which exceeds the VM limit:
import java.nio.ByteBuffer;
public class OOMDirectBuffer {
public static void main(String[] args) {
while (true) {
// Allocate a large direct ByteBuffer
ByteBuffer buffer = ByteBuffer.allocateDirect(Integer.MAX_VALUE);
}
}
}
In the above program ‘OOMDirectBuffer‘ class’s ‘main()’ method tries to create a very large java nio’s ByteBuffer object (i.e., Integer.MAX_VALUE). When this program is executed, you will see the ‘java.lang.OutOfMemoryError: Direct buffer memory’ reported in the console.
How to troubleshoot ‘OutOfMemoryError: Direct buffer memory’?
It is very easy to identify the root cause of ‘OutOfMemoryError: Direct buffer memory’. This error would be printed in the std error log (or console), with the stack trace of the code that is causing it. Example, when the above program is executed, you will see the following stack trace to be printed:
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
at java.nio.Bits.reserveMemory(Bits.java:695)
at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
at com.buggyapp.oom.OOMDirectBuffer.main(OOMDirectBuffer.java:11)
It clearly points out that problem originates on line #11 in the OOMDirectBuffer.java. Equipped with this information, one can easily isolate the root cause of the problem and fix it.
Conclusion
In this post, we’ve covered a range of topics, from understanding JVM memory regions to diagnosing and resolving ‘java.lang.OutOfMemoryError: Direct buffer memory’. We hope you’ve found the information useful and insightful. However, our discussion doesn’t stop here. Your experiences and insights are invaluable to us and to your fellow readers. We encourage you to share your encounters with ‘java.lang.OutOfMemoryError: Direct buffer memory’ in the comments below. Whether it’s a unique solution you’ve discovered, a best practice you swear by, or even just a personal anecdote, your contributions can enrich the learning experience for everyone.