Deep Dive into Java I/O: From BIO to Netty and AIO with System Call Traces

This article analyzes the actual Linux system calls performed by various Java I/O models—including BIO, NIO, epoll‑based multiplexing, Netty, and AIO—showing code examples, performance trade‑offs, and how each approach interacts with the kernel.

Alibaba Cloud Developer
Alibaba Cloud Developer
Alibaba Cloud Developer
Deep Dive into Java I/O: From BIO to Netty and AIO with System Call Traces

Preface

This article examines the actual OS system calls performed by Java I/O models on CentOS 7.5, tracing each step from socket creation to data exchange.

Viewing System Calls

Use strace -ff -o ./out java TestJava to capture system calls of any Java program.

1. BIO (Blocking I/O)

Startup

socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 5
bind(5, {sa_family=AF_INET, sin_port=htons(8090), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(5, 50) = 0
poll([{fd=5, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=5, revents=POLLIN}])
poll

blocks until an event occurs.

Client Connection

accept(5, {sa_family=AF_INET, sin_port=htons(10253), sin_addr=inet_addr("42.120.74.252")}, 16) = 6
clone(child_stack=0x7f013c5c4fb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, ...) = 13168
poll([{fd=5, events=POLLIN|POLLERR}], 1, -1)

Each accepted connection spawns a new thread, which then blocks on poll again.

Thread Handling

recvfrom(6, "hello,bio
", 8192, 0, NULL, NULL) = 10

The fourth argument 0 indicates a blocking call.

Advantages & Disadvantages

Code is simple and logic is clear.

Each connection requires a dedicated thread, leading to the C10K problem.

Misconception: Java 1.8 BIO still uses poll, which is efficient but limited by the stream API.

2. NIO (Non‑Blocking I/O)

Improves scalability by using non‑blocking channels, reducing the number of threads.

/**
 * Alipay.com Inc. Copyright (c) 2004-2020 All Rights Reserved.
 */
package io;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.LinkedList;
public class NIOSocket {
    private static LinkedList<SocketChannel> clients = new LinkedList<>();
    private static void startClientChannelHandleThread(){
        new Thread(() -> {
            while(true){
                ByteBuffer buffer = ByteBuffer.allocateDirect(4096);
                for(SocketChannel c : clients){
                    int num = 0;
                    try { num = c.read(buffer); } catch(IOException e){ e.printStackTrace(); }
                    if(num > 0){
                        buffer.flip();
                        byte[] clientBytes = new byte[buffer.limit()];
                        buffer.get(clientBytes);
                        System.out.println(c.socket().getPort() + ":" + new String(clientBytes));
                        buffer.clear();
                    }
                }
            }
        }).start();
    }
    public static void main(String[] args) throws IOException {
        ServerSocketChannel socketChannel = ServerSocketChannel.open();
        socketChannel.bind(new InetSocketAddress(9090));
        socketChannel.configureBlocking(true);
        startClientChannelHandleThread();
        while(true){
            SocketChannel client = socketChannel.accept();
            if(client != null){
                client.configureBlocking(false);
                System.out.println("client port :" + client.socket().getPort());
                clients.add(client);
            }
        }
    }
}

Advantages: far fewer threads, non‑blocking reads.

Disadvantages: still scans all connections (O(n) system calls) and incurs high CPU usage.

3. Multiplexing (select / poll / epoll)

Kernel notifies which sockets have data, eliminating user‑space scanning.

epoll Example

epoll_create(256) = 7
epoll_ctl(7, EPOLL_CTL_ADD, 5, {EPOLLIN, {u32=5, u64=4324783852322029573}}) = 0
epoll_ctl(7, EPOLL_CTL_ADD, 4, {EPOLLIN, {u32=4, u64=158913789956}}) = 0
epoll_wait(7, [{EPOLLIN, {u32=4, u64=158913789956}}], 8192, -1) = 1
accept(4, {sa_family=AF_INET, sin_port=htons(29597), sin_addr=inet_addr("42.120.74.252")}, 16) = 8
fcntl(8, F_SETFL, O_RDWR|O_NONBLOCK) = 0
epoll_ctl(7, EPOLL_CTL_ADD, 8, {EPOLLIN, {u32=8, u64=3212844375897800712}}) = 0

Note: the fourth argument -1 of epoll_wait means block.

Comparison of poll vs epoll shows that epoll reduces both the number and the cost of system calls, giving O(1) scalability.

4. Netty

Netty provides a high‑level framework with ready‑made encoders/decoders, simplifying network programming.

/**
 * Simplistic telnet server.
 */
public final class TelnetServer {
    static final boolean SSL = System.getProperty("ssl") != null;
    static final int PORT = Integer.parseInt(System.getProperty("port", SSL? "8992" : "8023"));
    public static void main(String[] args) throws Exception {
        final SslContext sslCtx;
        if (SSL) {
            SelfSignedCertificate ssc = new SelfSignedCertificate();
            sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
        } else {
            sslCtx = null;
        }
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .handler(new LoggingHandler(LogLevel.INFO))
             .childHandler(new TelnetServerInitializer(sslCtx));
            b.bind(PORT).sync().channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

Advantages: rich data‑processing components, clear separation of business logic, high performance via pooled ByteBuf.

Disadvantages: steeper learning curve for newcomers.

5. AIO

Java AIO builds on epoll (or kqueue) to provide asynchronous event dispatch while keeping the programming model simple.

# Startup (Proactor pattern)
epoll_create(256) = 5
epoll_ctl(5, EPOLL_CTL_ADD, 6, {EPOLLIN, {u32=6, u64=11590018039084482566}}) = 0
clone(child_stack=0x7f340ac06fb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, ...) = 22704
socket(AF_INET6, SOCK_STREAM, IPPROTO_IP) = 8
setsockopt(8, SOL_IPV6, IPV6_V6ONLY, [0], 4) = 0
setsockopt(8, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(8, {sa_family=AF_INET6, sin6_port=htons(9090), inet_pton(AF_INET6, "::", &sin6_addr)}, 28) = 0
listen(8, 50)

Advantages: the runtime handles task scheduling; developers only need to implement the processing logic.

Disadvantages: potential concurrency issues when multiple events for the same channel are processed by different threads, and the buffer API is less friendly than Netty’s.

6. Summary

System‑call analysis reveals how Netty interacts with the kernel: a boss thread creates an epoll for accepting connections, while several worker threads each own their own epoll to handle I/O, avoiding contention and keeping CPU usage low.

Choosing the right I/O model depends on workload characteristics: BIO is simple but unscalable; NIO reduces threads but still incurs scanning overhead; epoll‑based multiplexing offers the best scalability; Netty adds convenience at the cost of learning effort; AIO abstracts asynchronous handling but requires careful thread‑pool design.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaNettyI/Osystem calls
Alibaba Cloud Developer
Written by

Alibaba Cloud Developer

Alibaba's official tech channel, featuring all of its technology innovations.

0 followers
Reader feedback

How this landed with the community

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.