Backend Development 13 min read

Understanding Zero‑Copy in Java I/O, NIO, Netty and Messaging Systems

This article explains the concept of zero‑copy, its benefits for I/O performance, and how Java NIO, Netty, Kafka, RocketMQ and related APIs such as mmap+write and sendfile implement zero‑copy to avoid unnecessary data copying between kernel and user space.

Architect
Architect
Architect
Understanding Zero‑Copy in Java I/O, NIO, Netty and Messaging Systems

Zero‑copy means that data does not need to be copied back and forth between user space and kernel space, which greatly improves system performance. It is widely used in frameworks such as Java NIO, Netty, Kafka and RocketMQ.

I/O Concepts – All I/O operations move data into or out of buffers. When a process issues a read request, the kernel first checks if the required data is already in kernel space; if not, it commands the disk controller to write data directly into the kernel read buffer via DMA. The kernel then copies data to the process buffer, or for a write request copies user data to the kernel socket buffer and then to the NIC.

Because each copy consumes CPU cycles and memory bandwidth, zero‑copy techniques were introduced to eliminate these copies.

Zero‑Copy Mechanisms

mmap + write – Maps a file directly into the process address space, allowing the kernel to share the same physical pages between kernel and user space.

Sendfile – A system call that transfers data from a file descriptor to a socket descriptor entirely within kernel space, reducing both copies and context switches.

Virtual Memory – Modern operating systems use virtual addresses that can map multiple virtual addresses to the same physical page and allow the virtual address space to exceed physical memory. This enables the kernel and user space to share the same physical buffer, allowing DMA to fill a buffer visible to both.

Java Zero‑Copy

MappedByteBuffer – Provided by FileChannel.map() , it creates a memory‑mapped region of a file. The mapped region behaves like a ByteBuffer whose data resides on disk. Example:

public class MappedByteBufferTest {
    public static void main(String[] args) throws Exception {
        File file = new File("D://db.txt");
        long len = file.length();
        byte[] ds = new byte[(int) len];
        MappedByteBuffer mappedByteBuffer = new FileInputStream(file).getChannel()
            .map(FileChannel.MapMode.READ_ONLY, 0, len);
        for (int offset = 0; offset < len; offset++) {
            byte b = mappedByteBuffer.get();
            ds[offset] = b;
        }
        Scanner scan = new Scanner(new ByteArrayInputStream(ds)).useDelimiter(" ");
        while (scan.hasNext()) {
            System.out.print(scan.next() + " ");
        }
    }
}

The map() method signature is:

public abstract MappedByteBuffer map(FileChannel.MapMode mode, long position, long size) throws IOException;

Parameters:

MapMode – READ_ONLY, READ_WRITE, PRIVATE.

Position – Start offset of the mapping.

Size – Number of bytes to map.

PRIVATE mode implements copy‑on‑write, creating a private copy when the buffer is modified.

DirectByteBuffer – The concrete class instantiated by the mapping; it allocates off‑heap memory that does not consume JVM heap.

Manual off‑heap allocation example:

ByteBuffer directByteBuffer = ByteBuffer.allocateDirect(100);

Channel‑to‑Channel Transfer – FileChannel.transferTo() moves data directly between channels without an intermediate user‑space buffer.

public abstract long transferTo(long position, long count, WritableByteChannel target) throws IOException;

Netty Zero‑Copy – Netty provides composite and slice buffers to avoid copying when assembling or splitting messages. The CompositeChannelBuffer holds references to multiple buffers instead of copying their contents.

public class CompositeChannelBuffer extends AbstractChannelBuffer {
    private final ByteOrder order;
    private ChannelBuffer[] components;
    private int[] indices;
    private int lastAccessedComponentId;
    private final boolean gathering;
    public byte getByte(int index) {
        int componentId = componentId(index);
        return components[componentId].getByte(index - indices[componentId]);
    }
    ...
}

Other Zero‑Copy Uses

RocketMQ uses mmap + write for delivering messages to consumers.

Kafka employs sendfile to transfer persisted log data to the network.

Summary – Zero‑copy works by sharing the same physical memory between kernel and user space, similar to using object references in Java; only one copy of the data exists, reducing CPU usage and latency.

NettysendfileZero CopyJava NIOI/O performanceMappedByteBuffer
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.