零拷贝了解吗?

假如需要文件传输,使用传统I/O,数据读取和写入是用户空间到内核空间来回赋值,而内核空间的数据是通过操作系统的I/O接口从磁盘读取或者写入,这期间发生了多次用户态和内核态的上下文切换,以及多次数据拷贝。

1.png

为了提升I/O性能,就需要减少用户态与内核态的上下文切换内存拷贝的次数

这就用到了我们零拷贝的技术,零拷贝技术实现主要有两种:

  • mmap + write

mmap() 系统调⽤函数会直接把内核缓冲区⾥的数据「映射」到⽤户空间,这样,操作系统内核与⽤户空间就不需要再进⾏任何的数据拷⻉操作。

2.png

  • sendfile

在 Linux 内核版本 2.1 中,提供了⼀个专⻔发送⽂件的系统调⽤函数 sendfile() 。

⾸先,它可以替代前⾯的 read() 和 write() 这两个系统调⽤,这样就可以减少⼀次系统调⽤,也就减少了 2 次上下⽂切换的开销。

其次,该系统调⽤,可以直接把内核缓冲区⾥的数据拷⻉到 socket 缓冲区⾥,不再拷⻉到⽤户态,这样就只有 2 次上下⽂切换,和 3 次数据拷⻉。

3.png

很多开源项目如Kafka、RocketMQ都采用了零拷贝技术来提升IO效率。

标签: java, Java面试题, 操作系统, Java问题合集, Java编程, Java问题精选, Java常见问题, 操作系统面试题