这是一道高频的面试题,而且在很多技术中都使用到了,比如JAVANIO、kafka、Netty、linux等等 。作为一个非常重要的知识点,而且又是高频面试题,有必要从零开始好好地认识一下 。即使你是刚入门的同行,相信也能看的懂 。
OK,开始今天的文章 。
一、什么是零拷贝?
1、从一个案例说起
为了解释这个概念,我们先要从一个需求说起,说某天某领导给你下发了一个任务,完成一个从文件中读取数据,并传输到网络上的一个小程序 。代码很简单:
首先我们在我们的操作系统中找到这个文件,然后把数据先读到缓冲区,最后把缓冲区的数据发送到网络上 。代码是很简单,现在我们考虑一下,这个数据从电脑到网络整个传输的过程:
文章插图
现在我们可以看到1->2->3->4的整个过程一共经历了四次拷贝的方式,但是真正消耗资源和浪费时间的是第二次和第三次,因为这两次都需要经过我们的CPU拷贝,而且还需要内核态和用户态之间的来回切换 。想想看,我们的CPU资源是多么宝贵,要处理大量的任务 。还要去拷贝大量的数据 。如果能把CPU的这两次拷贝给去除掉,岂不快哉!!!既能节省CPU资源,还可以避免内核态和用户态之间的切换 。
这里还要先说一下用户态和内核态的区别:
处于用户态执行时,进程所能访问的内存空间和对象受到限制,其所处于占有的处理器是可被抢占的2、优化方案
处于内核态执行时,则能访问所有的内存空间和对象,且所占有的处理器是不允许被抢占的 。
要去除第二次和第三次之间的拷贝,Linux开发人员也早就注意到了这个问题,于是在linux 2.1内核中,添加了 “数据被copy到socket buffer”的动作,于是我们的javaNIO,可以直接调用transferTo()的方法,就可以实现这种现象 。
文章插图
现在一看,感觉性能资源都得到了很大的提升,不过现在还不并不是完美的 。因为这三次拷贝还用到了CPU的拷贝技术,就是第二次 。不过不要担心 。Linux开发人员比我们更加深谋远虑 。
3、零拷贝优化方案
在Linux2.4 内核做了优化,取而代之的是只包含关于数据的位置和长度的信息的描述符被追加到了socket buffer 缓冲区中 。DMA引擎直接把数据从内核缓冲区传输到协议引擎(protocol engine),从而消除了最后一次CPU copy 。经过上述过程,数据只经过了2次copy就从磁盘传送出去了 。这个才是真正的Zero-Copy
文章插图
注意:这里的零拷贝其实是根据内核状态划分的,在这里没有经过CPU的拷贝,数据在用户态的状态下,经历了零次拷贝,所以才叫做零拷贝,但不是说不拷贝 。如果之前看过我的Netty系列的前两篇文章,应该都知道里面为了解决拆包和粘包的问题,Netty会在每一个数据包里面加一些特殊描述符 。这里同样也是 。
OK 。现在我们已经了解了什么是零拷贝技术,下面我们再说一下那些数据结构会用到零拷贝技术 。
二、哪些地方会用到零拷贝技术
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 读写 。
(1)MAppedByteBuffer
MappedByteBuffer 是 NIO 基于内存映射(mmap)这种零拷贝方式的提供的一种实现,意思是把一个文件从 position 位置开始的 size 大小的区域映射为内存映像文件 。这样之添加地址映射,而不进行拷贝 。
(2)DirectByteBuffer
DirectByteBuffer 的对象引用位于 Java 内存模型的堆里面,JVM 可以对 DirectByteBuffer 的对象进行内存分配和回收管理,是 MappedByteBuffer 的具体实现类 。因此同样具有零拷贝技术 。
推荐阅读
- 做包子发面技巧和配方是什么?
- Steam|《艾尔登法环》Steam掌机画面对比 画面特效接近次世代主机
- 延迟退休成定局?全面实施后,哪些人吃亏?哪些人影响不大?
- C++语言之最全面的C++资源、框架大全
- 写给初级前端的面试经验与总结
- 零基础学平面设计难吗?
- 你知道居住环境对人的影响吗 租房风水面面观
- 吃米和面哪个容易消化?
- 羽绒服面料
- 减肥吃面食哪些比较好?