How to Fix java.lang.OufOfMemoryError: Direct Buffer Memory

Java allows an application to access non-heap memory by using direct byte buffer. Many high-performance applications uses direct byte buffer, along with memory mapped file for high-speed IO. And, while the ByteBuffer object is small itself, it can hold a large chunk of non-heap memory, which is outside of Garbage collection scope.  Which means garbage collector can not reclaim this memory. It is often used to store large data e.g. order or static data cache. Since generally your program allocates the large buffer e.g. size of 1GB or 2GB, you get "Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory" error, when you try to allocate memory by running following code

ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE_OF_BUFFER)

java.lang.OutOfMemoryError: Direct buffer memory
    at java.nio.Bits.reserveMemory(
    at java.nio.DirectByteBuffer.<init>(
    at java.nio.ByteBuffer.allocateDirect(

Now there could be multiple reasons for that e.g. either your system doesn't have enough heap memory, mostly the case when you are requesting a large chunk of memory, or memory hasn't been free from last usage.

First case, is pretty straight forward, as your application will fail to start in first attempt itself, and will not work until you add extra memory or reduce size of direct byte buffer.

In second case, there could be either memory leak, where your code is holding reference of ByteBuffer to prevent them from being garbage collected, and subsequently your off heap buffer.

Investigating java.lang.OutOfMemoryError: Direct buffer memory

How to solve java.lang.OutOfMemoryError: Direct buffer memory in Java

                                                                                                                                                                                                                                                                                                                                  This is no different than java.lang.OutOfMemoryError: Java Heap Space, so you can use all the techniques you know e.g. taking heap dump and analysing them to troubleshoot this error. If you are not using alerady then, you can use following JVM options to take heap dump in event of OutOfMemoryError :


2) You can use sun.misc.Cleaner class and Java reflection to call clean() method for freeing memory held by direct byte buffer. Since they are garbage collected using a phantom reference and a reference queue, you can still hold the memory allocated to direct byte buffer, even after discarding all references. By explicitly calling the clean() method of Cleaner, you have better chance of freeing memory and thus avoiding java.lang.OutOfMemoryError: Direct buffer memory. By the way, just remember that this is an internal class and Java doesn't provide any behaviour guarantee between different JRE versions. Also you  can not call clean() method of Cleaner directly, e.g. DirectByteBuffer.cleaner().clean() because DirectByteBuffer is a package-private class and not visible outside java.nio package. Only way to explicitly calling clean() is by using reflection e.g.

   Method cleanerMethod = buffer.getClass().getMethod("cleaner");
   Object cleaner = cleanerMethod.invoke(buffer);
   Method cleanMethod = cleaner.getClass().getMethod("clean");

3) One more thing, you can do to avoid java.lang.OutOfMemoryError: Direct buffer memory is increasing JVM default memory limit. By default, JVM allows 64MB for direct buffer memory, you can increase it by using JVM option -XX:MaxDirectMemorySize=512m.

That's all on How to fix java.lang.OutOfMemoryError: Direct buffer memory in Java. Let me know if you have faced this issue before or facing it now, I will try to help you here.


  1. I don't understand. First, you say that Direct Buffer is not allocated into heap, but before, when an OOM happens, you say "there could be multiple reasons for that e.g. either your system doesn't have enough heap memory, "

    is right ?


  2. I assume the author ment to say the most of the memory is allocated on the native heap but the very small wrapper object is obviously allocated on the JVM heap. So it is realtivly unlikly you get OOM from the JVM heap, but that's possible as an edge case

  3. Thanks, Nice write up,
    According the Sun documentation, the default value of -XX:MaxDirectMemorySize is 0 which means unbounded.

  4. I tried a online tool , it can read gc log.