(5)零拷贝实现原理

【(5)零拷贝实现原理】场景:文件读出数据,到另一台服务器上
伪代码File.read(file, buf, len); Socket.send(socket, buf, len); 4次数据拷贝,用户态和内核态区别
(5)零拷贝实现原理
文章图片
1、read()一次上下文切换用户态->内核态),底层用DMA(direct memory access)读磁盘文件,存储到内核地址空间读取缓存区
2、程序无法访问内核地址空间数据,从读取拷贝到用户缓冲区。第二次切换(内核态->用户态),可修改数据。
3、终目通过Socket传到另一个服务,send()第三次切换(用户态->内核态),缓冲区与目标套接字相关联,与读取缓冲区无关。
4、send()返回,第四次切换,DMA把数据从目标套接字相关的缓存区传到协议引擎进行发送。
1和4是由DMA负责,不会消耗CPU,只有过程2和3的拷贝需要CPU参与
好几次拷贝多余,影响性能
一、零拷贝优化 不需要操作内容,2和3多余,直接把内核态读取缓存冲区数据直接拷贝到套接字相关的缓存区
(5)零拷贝实现原理
文章图片
切换四次减到两次,拷贝四次减到三(其中DMA copy 2次,CPU copy 1次)
FileChannel的transferTo() 可以实现,数据从文件通道传输到给定可写字节通道, file.read()和socket.send()替换为transferTo()调用"
public void transferTo(long position, long count, WritableByteChannel target);
不是零拷贝(一次cpu)
二、零拷贝实现
(5)零拷贝实现原理
文章图片
1、transferTo()DMA 将文件拷贝到内核读取缓冲区
2、避免内容整体拷贝,只位置长度追加到套接字缓冲区,DMA 引擎直接把数据从内核缓冲区传到协议引擎,消除最后一次 CPU拷贝
ps:面试从用户态谈到内核态,socket谈到FileChannel,从NIO谈到Netty,从直接内存到CompositeBy

    推荐阅读