核心概念:
用户空间+内核空间+磁盘硬件
1.最原始的BIO场景下IO操作流程。
读取磁盘上的文件,然后经过网络,将文件发送到另外一个磁盘的过程。4次上下文切换,2次文件复制。
1、JVM发出read() 系统调用。
2、OS上下文切换到内核模式(第一次上下文切换)并将数据读取到内核空间缓冲区。(第一次拷贝:hardware ----> kernel buffer)
3、OS内核然后将数据复制到用户空间缓冲区(第二次拷贝: kernel buffer --> user buffer),然后read系统调用返回。而系统调用的返回又会导致一次内核空间到用户空间的上下文切换(第二次上下文切换)。
4、JVM处理代码逻辑并发送write()系统调用。
5、OS上下文切换到内核模式(第三次上下文切换)并从用户空间缓冲区复制数据到内核空间缓冲区(第三次拷贝: user buffer ——> kernel buffer)。
6、write系统调用返回,导致内核空间到用户空间的再次上下文切换(第四次上下文切换)。将内核空间缓冲区中的数据写到hardware(第四次拷贝: kernel buffer ——> hardware)。
- 总的来说,传统的I/O操作进行了4次用户空间与内核空间的上下文切换,以及4次数据拷贝。显然在这个用例中,从内核空间到用户空间内存的复制是完全不必要的,因为除了将数据转储到不同的buffer之外,我们没有做任何其他的事情。所以,我们能不能直接从hardware读取数据到kernel buffer后,再从kernel buffer写到目标地点不就好了。为了解决这种不必要的数据复制,操作系统出现了零拷贝的概念。注意,不同的操作系统对零拷贝的实现各不相同。在这里我们介绍linux下的零拷贝实现。
2.除去了用户空间和内核空间的文件复制。
3.DMA