iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >什么是零拷贝技术
  • 547
分享到

什么是零拷贝技术

2024-04-02 19:04:59 547人浏览 薄情痞子
摘要

本篇内容介绍了“什么是零拷贝技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、什么是零拷贝?1、从一个

本篇内容介绍了“什么是零拷贝技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一、什么是零拷贝?

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的拷贝,数据在用户态的状态下,经历了零次拷贝,所以才叫做零拷贝,但不是说不拷贝。

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 的具体实现类。因此同样具有零拷贝技术。

(3)FileChannel

FileChannel 定义了 transferFrom() 和 transferTo()  两个抽象方法,它通过在通道和通道之间建立连接实现数据传输的。

我们直接看Linux2.4的版本,socket缓冲区做了调整,DMA带收集功能。

(1)DMA从拷贝至内核缓冲区

(2)将数据的位置和长度的信息的描述符增加至内核空间(socket缓冲区)

(3)DMA将数据从内核拷贝至协议引擎

这个复制过程是零拷贝过程。

2、Netty

Netty 中的零拷贝和上面提到的操作系统层面上的零拷贝不太一样, 我们所说的 Netty 零拷贝完全是基于(Java 层面)用户态的。

(1)Netty 通过 DefaultFileRegion 类对FileChannel 的 tranferTo()  方法进行包装,相当于是间接的通过java进行零拷贝。

(2)我们的数据传输一般都是通过tcp/IP协议实现的,在实际应用中,很有可能一条完整的消息被分割为多个数据包进行网络传输,而单个的数据包对你而言是没有意义的,只有当这些数据包组成一条完整的消息时你才能做出正确的处理,而Netty可以通过零拷贝的方式将这些数据包组合成一条完整的消息供你来使用。

此时零拷贝的作用范围仅在用户空间中。那Netty是如何实现的呢?为此我们就要找到Netty进行数据传输的接口,这个接口一定包含了可以实现零拷贝的功能,这个接口就是ChannelBuffer。

既然有接口肯定就有实现类,一个最主要的实现类是CompositeChannelBuffer,这个类的主要作用是将多个ChannelBuffer组成一个虚拟的ChannelBuffer来进行操作

为什么说是虚拟的呢,因为CompositeChannelBuffer并没有将多个ChannelBuffer真正的组合起来,而只是保存了他们的引用,这样就避免了数据的拷贝,实现了Zero  Copy。

(3)ByteBuf 可以通过 wrap 操作把字节数组、ByteBuf、ByteBuffer 包装成一个 ByteBuf 对象,  进而避免了拷贝操作

(4)ByteBuf 支持 slice 操作, 因此可以将 ByteBuf 分解为多个共享同一个存储区域的 ByteBuf,避免了内存的拷贝

3、kafka

kafka索引文件使用的是 mmap + write 方式,数据文件使用的是 sendfile  方式。适用于系统日志消息这种高吞吐量的大块文件的数据持久化和传输。

如果有10个消费者,传统方式下,数据复制次数为4*10=40次,而使用“零拷贝技术”只需要1+10=11次,一次为从磁盘复制到页面缓存,10次表示10个消费者各自读取一次页面缓存。

“什么是零拷贝技术”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 什么是零拷贝技术

本文链接: https://www.lsjlt.com/news/83390.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 什么是零拷贝技术
    本篇内容介绍了“什么是零拷贝技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、什么是零拷贝1、从一个案...
    99+
    2024-04-02
  • Linux中零拷贝技术是什么
    这篇文章给大家分享的是有关Linux中零拷贝技术是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。引文在写一个服务端程序时(Web Server或者文件服务器),文件下载是一个基本功能。这时候服务端的任务是:将...
    99+
    2023-06-15
  • kafka零拷贝技术怎么应用
    Kafka零拷贝技术是一种优化技术,可以提高数据传输的效率,减少数据在内存和磁盘之间的拷贝次数。它的应用主要体现在以下几个方面: ...
    99+
    2023-10-27
    kafka
  • golang零拷贝技术怎么使用
    Go语言中的零拷贝技术主要通过使用unsafe.Pointer和reflect.SliceHeader来实现。下面是一个使用零拷贝技...
    99+
    2023-10-23
    golang
  • Linux零拷贝技术的用法
    这篇文章主要讲解了“Linux零拷贝技术的用法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux零拷贝技术的用法”吧!       1、为什么需...
    99+
    2023-06-05
  • 浅谈Linux的零拷贝技术
    前言 在linux系统内部缓存和内存容量都是有限的,更多的数据都是存储在磁盘中。对于Web服务器来说,经常需要从磁盘中读取数据到内存,然后再通过网卡传输给用户: 那么这也算一次I O的过程,都知道IO过程中需要状态的切...
    99+
    2023-04-28
    Linux 零拷贝 零拷贝技术
  • linux下的零拷贝技术介绍
    本篇内容主要讲解“linux下的零拷贝技术介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“linux下的零拷贝技术介绍”吧!传统的数据传输方式很长一段时间内,数据拷贝的认识仅仅停留在应用程序层...
    99+
    2023-06-13
  • 零拷贝Zero-Copy技术如何理解
    这篇文章将为大家详细讲解有关零拷贝Zero-Copy技术如何理解,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 1.前言今天和大家一起学习个底层技术点-零拷贝Zero-Copy。L...
    99+
    2023-06-15
  • 怎么理解Netty、Kafka中的零拷贝技术
    本篇内容介绍了“怎么理解Netty、Kafka中的零拷贝技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!...
    99+
    2024-04-02
  • kafka零拷贝的原理是什么
    Kafka的零拷贝(Zero-Copy)原理是通过避免数据在内核态和用户态之间的多次拷贝来提高性能和效率。在传统的网络数据传输过程中...
    99+
    2023-10-21
    kafka
  • java零拷贝的实现方式是什么
    本篇内容主要讲解“java零拷贝的实现方式是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java零拷贝的实现方式是什么”吧!1.什么是零拷贝零拷贝字面上的意思包括两个,“零”和“拷贝”:“...
    99+
    2023-06-29
  • 什么是深拷贝和浅拷贝
    深拷贝和浅拷贝分别是指:深拷贝是指拷贝对象的具体内容,二内存地址是自主分配的,拷贝结束之后俩个对象虽然存的值是一样的,但是内存地址不一样,俩个对象页互相不影响,互不干涉。浅拷贝是指对内存地址的复制,让目标对象指针和源对象指向同一片内存空间。...
    99+
    2023-10-29
  • JavaScript深拷贝与浅拷贝是什么
    这篇文章主要介绍了JavaScript深拷贝与浅拷贝是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1 浅拷贝概念深拷贝和浅拷贝是只针对Object和Array这样的引用...
    99+
    2023-06-29
  • 什么是Java浅拷贝和深拷贝
    这篇文章主要讲解了“什么是Java浅拷贝和深拷贝”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“什么是Java浅拷贝和深拷贝”吧!问题“如果你有一个对象, 并...
    99+
    2024-04-02
  • Linux零拷贝怎么实现
    本篇内容介绍了“Linux零拷贝怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!为了迅速建立起零拷贝的概念,我们拿一个常用的场景进行引...
    99+
    2023-06-16
  • Java深拷贝与浅拷贝的区别是什么
    这篇文章主要介绍“Java深拷贝与浅拷贝的区别是什么”,在日常操作中,相信很多人在Java深拷贝与浅拷贝的区别是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java深拷...
    99+
    2024-04-02
  • Linux中深拷贝与浅拷贝以及写时拷贝是什么意思
    这篇文章主要讲解了“Linux中深拷贝与浅拷贝以及写时拷贝是什么意思”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux中深拷贝与浅拷贝以及写时拷贝是什么意思”吧!假设B复制了A,当修改...
    99+
    2023-06-15
  • JavaScript中浅拷贝和深拷贝的区别是什么
    本篇文章为大家展示了JavaScript中浅拷贝和深拷贝的区别是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。前言1. 基础数据类型: undefined、bo...
    99+
    2024-04-02
  • 在java中深拷贝和浅拷贝区别是什么
    在java中深拷贝和浅拷贝区别:浅拷贝是指向被复制的内存地址,而深拷贝是创建新的内存地址用于存放复制的对象。浅拷贝对于引用类型的属性只是引用原对象的内存地址,而深拷贝是所有属性都创建新的对象。...
    99+
    2024-04-02
  • python中深拷贝和浅拷贝的区别是什么
    python中深拷贝和浅拷贝的区别是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。先深拷贝和浅拷贝都是对象的拷贝,都会生成一个看起来相同的对象,他们本质的区别是拷贝出来的对...
    99+
    2023-06-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作