Cut Page Load Time from 5 s to <1 s: Java IO, NIO, mmap & Zero‑Copy Tricks

This article explains why a Java page took five seconds to load, identifies three bottlenecks involving large BLOB fields and file I/O, and walks through four optimization steps—including lazy loading, buffered streams, memory‑mapped files, and sendFile zero‑copy—that reduce the load time to under one second.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
Cut Page Load Time from 5 s to <1 s: Java IO, NIO, mmap & Zero‑Copy Tricks

1. The truth behind a 5‑second page load

During a front‑end change a page took about 5 seconds to load, which is unacceptable. The “second‑open rate” (pages loading within 1 second) was far from being met.

Second‑open rate means a page can be loaded in under 1 second.

The query fetched the first 20 rows from the database, but three problems caused the delay:

A BLOB column stored a PDF template.

The PDF was written to local disk after the query.

When displayed online, the PDF was read from disk and sent through a socket.

Large‑field batch queries, file writes, and network transmission naturally take several seconds.

2. Four‑step optimization

1. “Lazy loading”

The PDF template is only needed when the user clicks the freight‑template button.

Optimization 1: Do not query the PDF when fetching the list.

Optimization 2: Query the PDF by its UUID on demand, triggering an index without sorting.

Optimization 3: Save the file to disk asynchronously.

2. Why reading the file was slow

The original code used FileReader, which reads the file character by character.

Optimization 4: Use buffered streams to read the file.

3. Understanding Java I/O streams

Java I/O abstracts input and output as streams. InputStream – abstract input byte stream. OutputStream – abstract output byte stream.

Character streams (Reader/Writer) convert between bytes and characters. BufferedInputStream and BufferedOutputStream provide buffering to reduce disk access.

Object streams allow serialization of Java objects.

4. Code examples

1. Reading with FileReader

private static int readFileByReader(String filePath) {
    int result = 0;
    try (Reader reader = new FileReader(filePath)) {
        int value;
        while ((value = reader.read()) != -1) {
            result += value;
        }
    } catch (Exception e) {
        System.out.println("readFileByReader exception: " + e);
    }
    return result;
}

2. Reading with BufferedReader

private static String readFileByBuffer(String filePath) {
    StringBuilder builder = new StringBuilder();
    try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
        String data;
        while ((data = reader.readLine()) != null) {
            builder.append(data);
        }
    } catch (Exception e) {
        System.out.println("readFileByReader exception: " + e);
    }
    return builder + "";
}

Testing with 150 000 simulated files shows FileReader takes ~8136 ms while BufferedReader takes ~6718 ms, a noticeable difference.

BufferedReader wraps a FileReader, providing a buffer that reduces the number of read‑system calls and character conversions, greatly improving I/O efficiency.

3. Buffered stream internals

Key points of buffered streams:

They use an 8192‑byte buffer; when empty, fill() reads more data from disk.

Buffered output streams flush the buffer to disk.

Most operations occur in memory, reducing CPU‑disk interactions.

Closing a buffered stream releases its buffer and underlying streams.

5. NIO FileChannel

Common methods

read

– read data into a buffer. write – write buffer data to the channel. transferFrom – copy data from another channel. transferTo – copy data to another channel.

Buffer and channel notes

ByteBuffer

requires matching put / get types.

Buffers can be made read‑only. MappedByteBuffer maps a file directly into memory.

Scattering/Gathering allow reading/writing with multiple buffers.

Selector

Selectors enable a single thread to monitor multiple channels for I/O events, reducing thread count and context‑switch overhead.

6. Memory‑mapped files (mmap)

mmap creates a virtual memory region that maps directly to a file, allowing the process to read/write as if it were memory, avoiding many traditional I/O calls.

In Java, FileChannel and MappedByteBuffer implement mmap.

public static String readFileByMmap(String filePath) {
    File file = new File(filePath);
    String ret = "";
    try (FileChannel channel = new RandomAccessFile(file, "r").getChannel()) {
        long size = channel.size();
        ByteBuffer buffer = ByteBuffer.allocate((int) size);
        while (channel.read(buffer) != -1) {}
        buffer.flip();
        byte[] data = new byte[buffer.remaining()];
        buffer.get(data);
        ret = new String(data);
    } catch (IOException e) {
        System.out.println("readFileByMmap exception: " + e);
    }
    return ret;
}

mmap reduces one CPU copy compared with buffered streams, though context switches remain.

7. Zero‑copy with sendFile

Traditional I/O involves four context switches and four memory copies.

sendFile eliminates the copy from kernel buffer to user space, achieving “zero‑copy” with only two context switches and two copies.

8. Summary

After four optimizations the page load time is under 1 second, improving the second‑open rate. The key steps are:

Avoid querying large BLOB fields in batch.

Lazy‑load the PDF on demand.

Store files asynchronously.

Read files via buffered streams → mmap → sendFile zero‑copy.

The article also covered Java I/O fundamentals, NIO FileChannel performance, mmap advantages, and zero‑copy techniques, with code comparisons demonstrating the speed differences.

JavaNIOmmapIO performancebuffered streamszero-copy
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

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.