3.5 Direct and indirect Buffers

3.5.1 Basic Introduction

  • Byte buffers are either direct or indirect. If it is a direct byte buffer, the Java virtual machine does its best to perform native I/O operations directly on this buffer. That is, the virtual machine tries to avoid copying the contents of the buffer into (or from) the intermediate buffer before (or after) each call to a native I/O operation of the underlying operating system.

  • Direct byte buffers can be created by calling the allocateDirect() factory method of this class. The buffers returned by this method are typically more expensive to allocate and unallocate than indirect buffers. The contents of the direct buffer can reside outside of the regular garbage collection heap, so their impact on the memory requirements of the application may not be noticeable. Therefore, it is recommended that direct buffers be allocated primarily to large, persistent buffers that are vulnerable to native I/O operations of the underlying system. In general, it is best to allocate direct buffers only when they provide a clear benefit in terms of program performance.

  • Direct byte buffers can also be created by mapping file regions directly into memory using FileChannel’s map() method. This method returns MappedByteBuffer. The Java platform implementation facilitates the creation of direct byte buffers from native code through JNI. If a buffer instance in one of these buffers refers to an unreachable memory region, attempting to access the region does not change the contents of the buffer and will result in an indeterminate exception being thrown at some point during the access or later.

  • Whether a byte buffer is a direct or indirect buffer can be determined by calling its isDirect() method. This method is provided to enable explicit buffer management in performance-critical code.

3.5.2 diagram

Indirect buffer

Direct buffer

    /** * Indirect buffers: allocate buffers in memory by using the allocate() method * direct buffers: allocate buffers in physical memory by using the allocateDirect() method, which improves efficiency */
    @Test
    public void test03(a) {
        // Allocate the direct buffer
        ByteBuffer buf = ByteBuffer.allocateDirect(1024);
        System.out.println("Determine if it is a direct buffer."+ buf.isDirect());
    }
Copy the code