Saturday, August 5, 2017

Difference between Direct, Non Direct and Mapped ByteBuffer in Java

ByteBuffer is one of the important class 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 f ByteBuffer, Direct, Non-Direct 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 method, to operate on memory mapped file. The main difference between direct and non-direct byte buffers are there 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 represent 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 their 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 the Definitive guide to Java Performance, one of the must-read books for Java programmers.

Direct vs Non-direct vs MappedByteBuffer in Java

As I said ByteBuffer is one of the very important class in a high-performance application. It is widely used in the high-frequency trading application, which strives for very low latency, mostly in sub-microsecond level. When I first mentioned about 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 derived from the fact that one is inside heap memory while other is outside 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.

Direct vs Non-Direct vs 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 file.

That's all on the difference between direct, non-direct and mapped byte buffer in Java. Just remember that Direct buffers are allocated outside heap and they are not in control of Garbage Collection while non-direct buffers are simply a wrapper around byte arrays, located inside heap. Memory mapped files can be accessed by using MappedByteBuffer, which is also a direct buffer. One more thing to remember is that 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.

Further Learning
Complete Java Masterclass
Java Fundamentals: The Java Language
Java Non-Blocking IO with Java.NIO and Design Patterns

Recommended Book for further reading
Java Performance The Definitive Guide By Scott Oaks [see here]
Pro Java 7 NIO.2 by Anghel Leonard [see here]

No comments :

Post a Comment