Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A simple rule of when I should use direct buffers with Java NIO for network I/O?

Can someone with the natural gift to explain complex things in an easy and straightforward way address this question? To acquire the best performance when should I use direct ByteBuffers versus regular ByteBuffers when doing network I/O with Java NIO?


For example: Should I read into a heap buffer and parse it from there, doing many get() (byte by byte) OR should I read it into a direct buffer and parse from the direct buffer?

like image 757
JohnPristine Avatar asked Aug 29 '12 23:08

JohnPristine


People also ask

What is a direct buffer Java?

A direct buffer is a chunk of native memory shared with Java from which you can perform a direct read. An instance of DirectByteBuffer can be created using the ByteBuffer. allocateDirect() factory method.

What is NIO buffer?

Advertisements. Buffers in Java NIO can be treated as a simple object which act as a fixed sized container of data chunks that can be used to write data to channel or read data from channel so that buffers act as endpoints to the channels.

How do buffers work in Java?

A buffer is essentially a block of memory into which you can write data, which you can then later read again. This memory block is wrapped in a NIO Buffer object, which provides a set of methods that makes it easier to work with the memory block.

How does NIO work in Java?

Java NIO enables you to do non-blocking IO. For instance, a thread can ask a channel to read data into a buffer. While the channel reads data into the buffer, the thread can do something else. Once data is read into the buffer, the thread can then continue processing it.


2 Answers

To acquire the best performance when should I use direct ByteBuffers versus regular ByteBuffers when doing network I/O with Java NIO?

Direct buffers have a number of advantages

  • The avoid an extra copy of data passed between Java and native memory.
  • If they are re-used, only the page used are turning into real memory. This means you can make them much larger than they need to me and they only waste virtual memory.
  • You can access multi-byte primitives in native byte order efficiently. (Basically one machine code instruction)

Should I read into a heap buffer and parse it from there, doing many get() (byte by byte) OR should I read it into a direct buffer and parse from the direct buffer?

If you are reading a byte at a time, you may not get much advantage. However, with a direct byte buffer you can read 2 or 4 bytes at a time and effectively parse multiple bytes at once.

[real time] [selectors]

If you are parsing real time data, I would avoid using selectors. I have found using blocking NIO or busy waiting NIO can give you the lowest latency performance (assuming you have a relatively small number of connections e.g. up to 20)

like image 88
Peter Lawrey Avatar answered Oct 22 '22 11:10

Peter Lawrey


A direct buffer is best when you are just copying the data, say from a socket to a file or vice versa, as the data doesn't have to traverse the JNI/Java boundary, it just stays in JNI land. If you are planning to look at the data yourself there's no point in a direct buffer.

like image 38
user207421 Avatar answered Oct 22 '22 11:10

user207421