Monday, May 23, 2022

Difference between Direct, Non Direct and Mapped ByteBuffer in Java?

ByteBuffer is one of the important classes of Java NIO API. It was introduced in java.nio package on JDK 1.4, it not only allows you to operate on heap byte arrays but also with direct memory, which resides outside the JVM. There are mainly three types of ByteBuffer in Java - Direct Byte Buffer, Non-Direct ByteBuffer, and mapped byte buffers. You can create both direct and non-direct buffers using java.nio.ByteBuffer class, while MappedByteBuffer is a subclass of ByteBuffer, which is created by FileChannel.map() method, to operate on memory-mapped file

The main difference between direct and non-direct byte buffers are their memory location, non-direct byte buffers are just a wrapper around byte array and they reside in Java Heap memory while direct byte buffer is outside of JVM and memory is not allocated from the heap.

You can also remember this fact by their name, Direct indicates working with memory directly. Due to this reason, direct byte buffers are also not affected by Garbage Collection. MappedByteBuffer is also a type of direct byte buffer, which represents a memory-mapped region of a file.

In this Java NIO tutorial, you will see a couple of more differences between direct, non-direct, and mapped byte buffers, which will help you to understand the concept and its usage better.

If you love books like me and wants to learn advanced concept e.g. high performance and low latency application development, performance tuning, and JVM internals, I suggest taking a look at these Java Performance online courses, a great resource for Java programmers.




Difference between Direct vs Non-direct vs MappedByteBuffer in Java

As I said ByteBuffer is one of the very important classes in a high-performance application. It is widely used in the high-frequency trading application, which strives for very low latency, mostly in the sub-microsecond level. 

When I first mentioned a memory-mapped file in Java, I have outlined some benefits of using those files, and ByteBuffer class is key to operate them. Most of the differences between direct and non-direct ByteBuffer are derived from the fact that one is inside heap memory while the other is outside the heap.

1. The first difference between non-direct and direct byte buffer comes from the fact, how you create them. You can create non-direct byte buffer either by allocating space for buffer's content or by wrapping an existing byte array into a buffer. While a Direct byte buffer may be created by calling factory method allocateDirect() or by mapping a region of a file directly into memory , known  as MappedByteBuffer.

2. In the case of Direct byte buffer, JVM performs native IO operation directly into the buffer, without copying them into any intermediate buffer, this makes it very attractive for performing high-speed IO operation on them, but this facility comes with care. 

If a memory-mapped file is shared between multiple processes then you need to ensure that it won't get corrupted i.e. some regions of memory-mapped file not becoming unavailable.

3. One more difference between direct and non-direct byte buffers are that former's memory footprint may not be obvious because they are allocated outside of Java heap while non-direct buffers consume heap space and are subject to garbage collection.


4. You can check whether a byte buffer is direct or non-direct by calling isDirect() method from java.nio.ByteBuffer class. It returns true if byte buffer is direct.

Difference between Direct, Non Direct and Mapped ByteBuffer in Java?


These were some differences between direct, non-direct, and mapped byte buffers in Java. If you are working in high volume low latency systems than most of the  cases you will work with either direct or mapped byte buffers. 

Since ByteBuffer indexes are integer based, which effectively limits their addressable space up to 2GB, you may want to check BigByteBuffer class from Java 1.7 NIO package, which provides long indexes, alternatively, you can also use offsets to map different regions of memory-mapped files.


That's all on the difference between direct, non-direct, and mapped byte buffer in Java. Just remember that Direct buffers are allocated outside the heap and they are not in control of Garbage Collection while non-direct buffers are simply a wrapper around byte arrays, located inside the heap.

Memory mapped files can be accessed by using MappedByteBuffer, which is also a direct buffer. One more thing to remember is that the default order of bytes in ByteBuffer is BIG_ENDIAN, which means the bytes of a multibyte value are ordered from most significant to least significant.

Other Java IO tutorials you may like:
  • How to convert ByteBuffer to String in Java? (example)
  • How to read CSV files in Java? (program)
  • How to append data into an existing file in Java? (answer)
  • How to read the file line by line in Java using BufferedReader and Scanner? (answer)
  • How to read the file in one line in Java 8? (solution)
  • How to Fix java.lang.OufOfMemoryError: Direct Buffer Memory in Java (solution)
  • Difference between heap and stack in Java? (heap vs stack)
  • How to read/write an Excel file in Java? (program)
  • 15 Java NIO Interview Questions with answers (NIO questions)
Thanks for reading this article so far. If you like these difference between different types of Bytebuffers in Java then please share with your friends and colleagues. 



No comments:

Post a Comment