首页 > Web开发 > 详细

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

时间:2020-02-25 02:43:13      阅读:73      评论:0      收藏:0      [点我收藏+]

这里只是感性地认识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拷贝。

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

原文:https://www.cnblogs.com/AllenDuke/p/12359557.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!