NIO学习笔记,从Linux IO演化模型到Netty—— Linux零拷贝

这里只是感性地认识Linux零拷贝,不涉及具体细节。

 

1.Linux传统的数据拷贝

 

 用户进程是不能直接访问文件系统的,要先切换到内核态,发起系统调用,DMA把磁盘中的数据写入内核空间,内核再把数据拷贝到用户空间,用户进程才能操作这些数据。

如上把磁盘上的文件发送到网络,将会发生4次状态切换,2次cpu拷贝。

 

 2. 2.4版本前

(1)基于mmap(可修改数据)+write

 

 将会有4次状态切换,1次cpu拷贝。

因为内存映射总是要对齐页边界(最小单位为4kb),所以可能会造成碎片空间的浪费,一个5kb的文件要映射占用8kb的空间,浪费了3kb。

 (2)基于sendFile(不可修改数据,jdk nio中transferFrom,transferTo,数据从一个channel直接传输到另一个channel便是依赖于此)

 

 将会有2次状态切换,1次cpu拷贝。

 

3.  2.4版本后,基于mmap(用于修改数据,后续版本中如果共享区为多个进程共有,将会写时复制,拷贝到用户空间)+gather

 

 Linux 2.4 版本的内核对 sendfile 系统调用进行修改,为 DMA (要硬件支持)拷贝引入了 gather 操作。它将内核空间(kernel space)的读缓冲区(read buffer)中对应的数据描述信息(内存地址、地址偏移量)记录到相应的网络缓冲区( socket buffer)中,由 DMA 根据内存地址、地址偏移量将数据批量地从读缓冲区(read buffer)拷贝到网卡设备中。

将有2次状态切换,0次cpu拷贝。

 

4. 2.6.17版本后,splice(用户进程不能修改数据)

 splice 系统调用(不需硬件支持)可以在内核空间的读缓冲区(read buffer)和网络缓冲区(socket buffer)之间建立管道(pipeline),从而避免了两者之间的 CPU 拷贝操作。

将有2次状态切换,0次cpu拷贝。

posted @ 2020-02-24 23:34  Allen没有青春  阅读(200)  评论(0编辑  收藏  举报