认识零拷贝

简介: 认识零拷贝

注意事项


(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

目录
相关文章
|
API PHP C++
Windows下用vs2017编译和配置libcurl库(手把手教,适合新人)
Windows下用vs2017编译和配置libcurl库(手把手教,适合新人)
2669 0
|
8月前
|
人工智能 自然语言处理 应用服务中间件
Bolt.diy 创意建站方案测评 | 不懂代码,你也可以快速建站
本文详细介绍了一款名为Bolt.diy的创意建站工具的使用流程与功能体验。Bolt.diy是阿里云推出的一款基于自然语言交互的Web开发工具,用户可通过简单描述需求快速生成个性化网站。文章从开通服务、配置API-Key到实际创建网站进行了详细步骤解析,并展示了如何通过本地nginx部署生成的代码。此外,还尝试了优化初级会计考试招生宣传页面的过程,发现目前工具在图片资源处理和一键发布功能上存在局限性。整体来看,Bolt.diy操作便捷、成本可控,适合个人及企业低成本验证创意需求。
|
11月前
|
机器学习/深度学习 人工智能 自然语言处理
|
存储 安全 开发工具
GitHub 支持双因素认证(2FA)
【9月更文挑战第29天】
2059 6
|
存储 监控 固态存储
elasticsearch索引生命周期管理(ILM):原理和实践
elasticsearch索引生命周期管理(ILM):原理和实践
|
机器学习/深度学习 自然语言处理
【AIGC】探索大语言模型中的词元化技术机器应用实例
【AIGC】探索大语言模型中的词元化技术机器应用实例
292 0
|
SQL 资源调度 数据库连接
Hive怎么调整优化Tez引擎的查询?在Tez上优化Hive查询的指南
在Tez上优化Hive查询,包括配置参数调整、理解并行化机制以及容器管理。关键步骤包括YARN调度器配置、安全阀设置、识别性能瓶颈(如mapper/reducer任务和连接操作),理解Tez如何动态调整mapper和reducer数量。例如,`tez.grouping.max-size` 影响mapper数量,`hive.exec.reducers.bytes.per.reducer` 控制reducer数量。调整并发和容器复用参数如`hive.server2.tez.sessions.per.default.queue` 和 `tez.am.container.reuse.enabled`
1490 0
|
存储 Unix Linux
Linux 信号介绍/列表:列举Linux系统中常见的信号及其含义和用途
Linux 信号介绍/列表:列举Linux系统中常见的信号及其含义和用途
494 0
|
传感器 安全 编译器
【C++断言机制】深入理解C/C++ 中静态断言static_assert与断言 assert
【C++断言机制】深入理解C/C++ 中静态断言static_assert与断言 assert
526 0
|
JavaScript
vue实现下拉列表远程搜索示例(根据关键词模糊搜索)
vue实现下拉列表远程搜索示例(根据关键词模糊搜索)
1468 0
vue实现下拉列表远程搜索示例(根据关键词模糊搜索)