There are use cases where data need to be read from source to a sink without modification. In code this might look quite simple: for example in Java, you may read data from one InputStream
chunk by chunk into a small buffer (typically 8KB), and feed them into the OutputStream
, or even better, you could create a PipedInputStream
, which is basically just a util that maintains that buffer for you. However, if low latency is crucial to your software, this might be quite expensive from the OS perspective and I shall explain.
What happens under the hood
Well, here’s what happens when the above code is used:
- JVM sends read() syscall.
- OS context switches to kernel mode and reads data into the input socket buffer.
- OS kernel then copies data into user buffer, and context switches back to user mode. read() returns.
- JVM processes code logic and sends write() syscall.
- OS context switches to kernel mode and copies data from user buffer to output socket buffer.
- OS returns to user mode and logic in JVM continues.