做视频特效的网站,上传网站怎么安装,网站权重不稳定,电商网站代码设计文章目录 什么是零拷贝3、零拷贝优化方案 - 真正的零拷贝哪些地方会用到零拷贝技术 现在来谈谈零拷贝#xff0c;以及在开发中哪些地方使用到零拷贝。 开干… 什么是零拷贝
零拷贝指的是#xff0c;从一个存储区域到另一个存储区域的copy任务无需CPU参与就可完成。零拷贝的底… 文章目录 什么是零拷贝3、零拷贝优化方案 - 真正的零拷贝哪些地方会用到零拷贝技术 现在来谈谈零拷贝以及在开发中哪些地方使用到零拷贝。 开干… 什么是零拷贝
零拷贝指的是从一个存储区域到另一个存储区域的copy任务无需CPU参与就可完成。零拷贝的底层是 通过DMA总线技术实现的。零拷贝与具体的编程语言无关完全依赖于OSOS支持就可使用不支持 设置了也不起作用。 DMADirect Memory Access直接内存访问是一种计算机系统内部的数据传输技术需要DMA总 线硬件的体系结构的硬件支持。其整个数据传输过程是在DMA控制器下完成的。 零拷贝在计算机内部数据拷贝及网络传输中都大量使用用于减少CPU消耗和内存带宽占用减少用户 空间与内核空间的拷贝过程减少用户态与内核态间的切换次数提高系统效率提升系统性能。例如 远程服务器处理客户端浏览器的主页打开请求过程就是一个零拷贝在网络传输中的典型应用。下面全 部以该场景为例进行分析。 现在我们可以看到1-2-3-4的整个过程一共经历了四次拷贝的方式**但是真正消耗资源和浪费时间的是第二次和第三次因为这两次都需要经过我们的CPU拷贝而且还需要内核态和用户态之间的来回切换。**想想看我们的CPU资源是多么宝贵要处理大量的任务。还要去拷贝大量的数据。如果能把CPU的这两次拷贝给去除掉岂不快哉既能节省CPU资源还可以避免内核态和用户态之间的切换。
这里还要先说一下用户态和内核态的区别
处于用户态执行时进程所能访问的内存空间和对象受到限制其所处于占有的处理器是可被抢占的处于内核态执行时则能访问所有的内存空间和对象且所占有的处理器是不允许被抢占的。 现在一看感觉性能资源都得到了很大的提升不过现在还不并不是完美的。因为这三次拷贝还用到了CPU的拷贝技术就是第二次。不过不要担心。Linux开发人员比我们更加深谋远虑。
3、零拷贝优化方案 - 真正的零拷贝
在Linux2.4 内核做了优化取而代之的是只包含关于数据的位置和长度的信息的描述符被追加到了socket buffer 缓冲区中。DMA引擎直接把数据从内核缓冲区传输到协议引擎protocol engine从而消除了最后一次CPU copy。经过上述过程数据只经过了2次copy就从磁盘传送出去了。这个才是真正的Zero-Copy
注意这里的零拷贝其实是根据内核状态划分的在这里没有经过CPU的拷贝数据在用户态的状态下经历了零次拷贝所以才叫做零拷贝但不是说不拷贝。 哪些地方会用到零拷贝技术
1、java的NIO
先说java是因为要给下面的netty做铺垫在 Java NIO 中的通道Channel就相当于操作系统的内核空间kernel space的缓冲区而缓冲区Buffer对应的相当于操作系统的用户空间user space中的用户缓冲区user buffer。
堆外内存DirectBuffer在使用后需要应用程序手动回收而堆内存HeapBuffer的数据在 GC 时可能会被自动回收。因此在使用 HeapBuffer 读写数据时为了避免缓冲区数据因为 GC 而丢失NIO 会先把 HeapBuffer 内部的数据拷贝到一个临时的 DirectBuffer 中的本地内存native memory这个拷贝涉及到 sun.misc.Unsafe.copyMemory() 的调用背后的实现原理与 memcpy() 类似。 最后将临时生成的 DirectBuffer 内部的数据的内存地址传给 I/O 调用函数这样就避免了再去访问 Java 对象处理 I/O 读写。
1MappedByteBuffer
MappedByteBuffer 是 NIO 基于内存映射mmap这种零拷贝方式的提供的一种实现意思是把一个文件从 position 位置开始的 size 大小的区域映射为内存映像文件。这样之添加地址映射而不进行拷贝。
2DirectByteBuffer
DirectByteBuffer 的对象引用位于 Java 内存模型的堆里面JVM 可以对 DirectByteBuffer 的对象进行内存分配和回收管理是 MappedByteBuffer 的具体实现类。因此同样具有零拷贝技术。
3FileChannel
FileChannel 定义了 transferFrom() 和 transferTo() 两个抽象方法它通过在通道和通道之间建立连接实现数据传输的。
我们直接看Linux2.4的版本socket缓冲区做了调整DMA带收集功能。
1DMA从拷贝至内核缓冲区
2将数据的位置和长度的信息的描述符增加至内核空间(socket缓冲区)
3DMA将数据从内核拷贝至协议引擎
这个复制过程是零拷贝过程。
2、Netty
Netty 中的零拷贝和上面提到的操作系统层面上的零拷贝不太一样, 我们所说的 Netty 零拷贝完全是基于Java 层面用户态的。
1Netty 通过 DefaultFileRegion 类对FileChannel 的 tranferTo() 方法进行包装相当于是间接的通过java进行零拷贝。
2我们的数据传输一般都是通过TCP/IP协议实现的在实际应用中很有可能一条完整的消息被分割为多个数据包进行网络传输而单个的数据包对你而言是没有意义的只有当这些数据包组成一条完整的消息时你才能做出正确的处理而Netty可以通过零拷贝的方式将这些数据包组合成一条完整的消息供你来使用。
此时零拷贝的作用范围仅在用户空间中。那Netty是如何实现的呢为此我们就要找到Netty进行数据传输的接口这个接口一定包含了可以实现零拷贝的功能这个接口就是ChannelBuffer。
既然有接口肯定就有实现类一个最主要的实现类是CompositeChannelBuffer这个类的主要作用是将多个ChannelBuffer组成一个虚拟的ChannelBuffer来进行操作
为什么说是虚拟的呢因为CompositeChannelBuffer并没有将多个ChannelBuffer真正的组合起来而只是保存了他们的引用这样就避免了数据的拷贝实现了Zero Copy。
3ByteBuf 可以通过 wrap 操作把字节数组、ByteBuf、ByteBuffer 包装成一个 ByteBuf 对象, 进而避免了拷贝操作
4ByteBuf 支持 slice 操作, 因此可以将 ByteBuf 分解为多个共享同一个存储区域的 ByteBuf避免了内存的拷贝
3、kafka
Kafka 的索引文件使用的是 mmap write 方式数据文件使用的是 sendfile 方式。适用于系统日志消息这种高吞吐量的大块文件的数据持久化和传输。
如果有10个消费者传统方式下数据复制次数为4*1040次而使用“零拷贝技术”只需要11011次一次为从磁盘复制到页面缓存10次表示10个消费者各自读取一次页面缓存。