认识零拷贝

简介: 认识零拷贝

注意事项


(1)零拷贝的含义是数据不从内核空间拷贝到用户空间,也不从用户空间拷贝到内核空间

(2)零拷贝完全依赖操作系统,操作系统提供了就是提供了,没有提供就没有提供,java本身做不了任何事情


传统的IO拷贝


需求


java读取磁盘上的文件,并且输出出去。这个过程包含两个步骤,一个是读,一个是写


图片解读


5.png


三列分别为用户空间、内核空间、硬件


(1)read() syscall :java客户端(jvm虚拟机)向操作系统发起读磁盘数据的请求

(2)ask for data :系统向磁盘读数据

(3)data to kernel buffer through DMA: 磁盘数据通过DMA读到内核缓存区

(4)copy data to user buffer :把数据内核缓冲区复制到用户缓冲区(java堆)中

(5)code logic coutinues:业务逻辑处理

(6)wirte() syscall,copies data to kernel socket buffer:java客户端向系统发起写请求,并且把用户缓冲区(java堆)数据复制到内核缓冲区

(7)weites data:从内核缓冲区写到磁盘

(8)done:返回结果

(9)write() returns:返回写入结果


图片分析


上图有4次上下文切换:

(1)read() syscall :java客户端(jvm虚拟机)向操作系统发起读磁盘数据的请求  ----》从用户态切换为内核态


(4)copy data to user buffer :把数据内核缓冲区复制到用户缓冲区(java堆)中----》从内核态切换为用户态


(6)wirte() syscall,copies data to kernel socket buffer:java客户端向系统发起写请求,并且把用户缓冲区(java堆)数据复制到内核缓冲区----》从用户态切换为内核态


(9)write() returns:返回写入结果----》从内核态切换为用户态


上图有2次没有必要的数据拷贝(假设没有步骤5):


(4)copy data to user buffer :把数据内核缓冲区复制到用户缓冲区(java堆)中


(6)wirte() syscall,copies data to kernel socket buffer:java客户端向系统发起写请求,并且把用户缓冲区(java堆)数据复制到内核缓冲区


代码


InputStream 、OutputStream


零拷贝


图片解读


(1)sendfile() syscall : java客户端(jvm虚拟机)向操作系统发起读磁盘数据sendfile的请求

(2)ask for data :系统向磁盘读数据

(3)data to kernel buffer through DMA: 磁盘数据通过DMA读到内核缓存区

(4)wirte data to target socket buffer:从内核空间缓冲区写到socket缓冲区

(5)writes data:socket向目标发送数据

(6)done:返回结果

(7) sendfile() returns :返回sendfile结果



6.png


图片分析


上图有2次上下文切换(比传统的IO减少了2次切换):


(1)sendfile() syscall : java客户端(jvm虚拟机)向操作系统发起读磁盘数据sendfile的请求 ----》从用户态切换为内核态


(7) sendfile() returns :返回sendfile结果----》从内核态切换为用户态


上图有3次数据拷贝(比传统的IO减少了1次):


(3)data to kernel buffer through DMA: 磁盘数据通过DMA读到内核缓存区


(4)wirte data to target socket buffer:从内核空间缓冲区写到socket缓冲区


(5)writes data:socket向目标发送数据


代码


 fileChannel.transferTo(, , );
 fileChannel.transferFrom(, , );


零拷贝升级版


升级版需要解决的问题:

上面零拷贝的第四步((4)从内核空间缓冲区写到socket缓冲区)是可以优化的


图片解读


看图片的下半部分:


看kernel buffer ---------------> socket buffer


Linux2.4之前的零拷贝是把 kernel buffer 中全部的数据 拷贝 到 socket buffer


Linux2.4之后的零拷贝是把kernel buffer中的地址和数据长度拷贝到到 socket buffer(优化后),类似


当真正发送数据的时候,客户端会从socketbuffer中拿到地址和数据长度找到kernel buffer 进行发送


这个过程只有2次数据拷贝,是真正意义上的零拷贝


7.png


8.png

目录
相关文章
|
13天前
|
存储 缓存 算法
零拷贝
零拷贝
20 1
零拷贝
|
1月前
|
安全 NoSQL Java
一文搞懂网络通信的基石✅IO模型与零拷贝
【10月更文挑战第1天】本文深入探讨了网络通信中的IO模型及其优化方法——零拷贝技术。首先介绍了IO模型的概念及五种常见类型:同步阻塞、同步非阻塞、多路复用、信号驱动和异步IO模型。文章详细分析了每种模型的特点和适用场景,特别是多路复用和异步IO在高并发场景中的优势。接着介绍了零拷贝技术,通过DMA直接进行数据传输,避免了多次CPU拷贝,进一步提升了效率。最后总结了各种模型的优缺点,并提供了相关的代码示例和资源链接。
一文搞懂网络通信的基石✅IO模型与零拷贝
|
1月前
|
Java 大数据 Linux
《揭秘高性能 I/O 利器:mmap 内存映射与 sendfile 技术》
本文详细解析了mmap内存映射和sendfile技术,探讨了它们的工作原理、优势及应用场景,帮助读者理解如何通过这些技术提升数据传输效率,并提供了实际代码示例,为技术选型提供参考。关键词:mmap、sendfile、高性能I/O、零拷贝。
59 0
|
6月前
|
Linux 数据处理
什么是零拷贝
什么是零拷贝
|
6月前
|
缓存 Linux
零拷贝技术(DMA、MMAP、sendfile)
零拷贝技术(DMA、MMAP、sendfile)
326 0
|
缓存 网络协议 Linux
零拷贝技术:减少数据复制和上下文切换,提高网络传输效率(下)
本章节主要讨论了如何通过零拷贝技术来优化文件传输的性能。零拷贝技术主要通过减少用户态和内核态之间的上下文切换次数和数据拷贝次数来提高性能。具体来说,介绍了两种实现零拷贝的方式:mmap + write和sendfile。使用mmap + write可以减少一次数据拷贝过程,而使用sendfile系统调用可以进一步减少系统调用和数据拷贝次数。此外,还介绍了如果网卡支持SG-DMA技术,可以通过DMA将数据直接拷贝到网卡缓冲区,实现真正的零拷贝。通过这些优化方法,可以显著提高文件传输的性能。
294 0
零拷贝技术:减少数据复制和上下文切换,提高网络传输效率(下)
|
缓存 Java
5.3 零拷贝
5.3 零拷贝
51 1
|
算法 网络协议 调度
零拷贝技术:减少数据复制和上下文切换,提高网络传输效率(上)
在本次讨论中,我们确实只是提到了DMA技术在文件传输过程中的重要作用,并对零拷贝技术进行了简要介绍。然而,网络传输中存在的问题和优化方法是一个庞大的话题,涉及到诸多方面。因此,我决定将这些问题的详细讨论留到下一篇文章中,以便更全面地探讨网络传输的优化。我希望通过这样的讨论,能够为读者提供有益的信息和思路,感谢大家的阅读和关注,期待在下一篇文章中与大家再次交流和分享关于网络传输的优化问题。
106 0
|
消息中间件 存储 网络协议
超硬核,基于mmap和零拷贝实现高效的内存共享(下)
超硬核,基于mmap和零拷贝实现高效的内存共享
|
消息中间件 存储 Kafka
超硬核,基于mmap和零拷贝实现高效的内存共享(上)
超硬核,基于mmap和零拷贝实现高效的内存共享