什么是 Java中的零拷贝

news2024/11/25 14:30:24

什么是零拷贝

WIKI中对其有如下定义:

“Zero-copy” describes computer operations in which the CPU does not perform the task of copying data from one memory area to another.

从WIKI的定义中,我们看到“零拷贝”是指计算机操作的过程中,CPU不需要为数据在内存之间的拷贝消耗资源。而它通常是指计算机在网络上发送文件时,不需要将文件内容拷贝到用户空间(User Space)而直接在内核空间(Kernel Space)中传输到网络的方式。

零拷贝给我们带来的好处

  • 减少甚至完全避免不必要的CPU拷贝,从而让CPU解脱出来去执行其他的任务
  • 减少内存带宽的占用
  • 通常零拷贝技术还能够减少用户空间和操作系统内核空间之间的上下文切换

零拷贝的实现

零拷贝实际的实现并没有真正的标准,取决于操作系统如何实现这一点。零拷贝完全依赖于操作系统。操作系统支持,就有;不支持,就没有。不依赖Java本身。

传统I/O

在Java中,我们可以通过InputStream从源数据中读取数据流到一个缓冲区里,然后再将它们输入到OutputStream里。我们知道,这种IO方式传输效率是比较低的。那么,当使用上面的代码时操作系统会发生什么情况:

img

传统IO.jpg

这是一个从磁盘文件读取并且通过socket写出的过程,对应的系统调用如下:

read(file,tmp_buf,len)
write(socket,tmp_buf,len)
  1. 程序使用read()系统调用。系统由用户态转换为内核态(第一次上线文切换),磁盘中的数据有DMA(Direct Memory Access)的方式读取到内核缓冲区(kernel buffer)。DMA过程中CPU不需要参与数据的读写,而是DMA处理器直接将硬盘数据通过总线传输到内存中。
  2. 系统由内核态转换为用户态(第二次上下文切换),当程序要读取的数据已经完成写入内核缓冲区以后,程序会将数据由内核缓存区,写入用户缓存区),这个过程需要CPU参与数据的读写。
  3. 程序使用write()系统调用。系统由用户态切换到内核态(第三次上下文切换),数据从用户态缓冲区写入到网络缓冲区(Socket Buffer),这个过程需要CPU参与数据的读写。
  4. 系统由内核态切换到用户态(第四次上下文切换),网络缓冲区的数据通过DMA的方式传输到网卡的驱动(存储缓冲区)中(protocol engine)

可以看到,传统的I/O方式会经过4次用户态和内核态的切换(上下文切换),两次CPU中内存中进行数据读写的过程。这种拷贝过程相对来说比较消耗资源

内存映射方式I/O

img

tmp_buf = mmap(file, len);
write(socket, tmp_buf, len);

这是使用的系统调用方法,这种方式的I/O原理就是将用户缓冲区(user buffer)的内存地址和内核缓冲区(kernel buffer)的内存地址做一个映射,也就是说系统在用户态可以直接读取并操作内核空间的数据。

  1. mmap()系统调用首先会使用DMA的方式将磁盘数据读取到内核缓冲区,然后通过内存映射的方式,使用户缓冲区和内核读缓冲区的内存地址为同一内存地址,也就是说不需要CPU再讲数据从内核读缓冲区复制到用户缓冲区。
  2. 当使用write()系统调用的时候,cpu将内核缓冲区(等同于用户缓冲区)的数据直接写入到网络发送缓冲区(socket buffer),然后通过DMA的方式将数据传入到网卡驱动程序中准备发送。

可以看到这种内存映射的方式减少了CPU的读写次数,但是用户态到内核态的切换(上下文切换)依旧有四次,同时需要注意在进行这种内存映射的时候,有可能会出现并发线程操作同一块内存区域而导致的严重的数据不一致问题,所以需要进行合理的并发编程来解决这些问题。

Java 中的 零 copy

Java中的零拷贝(Zero-copy)是指通过避免数据在不同内存区域之间的重复拷贝,从而提高数据传输的效率和性能的一种技术。在传统的数据传输过程中,数据需要从应用程序的内存中拷贝到操作系统内核的缓冲区中,然后再从操作系统内核的缓冲区中拷贝到网络设备的缓冲区中,最后再通过网络设备传输到远程设备的缓冲区中,这个过程中会涉及到多次的数据拷贝操作,这些拷贝操作会占用大量的CPU时间和内存带宽,从而影响系统的性能和效率。

具体实现

Java中的零拷贝技术通过使用直接内存缓冲区(Direct ByteBuffer)和Java NIO(New IO)库来实现。直接内存缓冲区是一种特殊的缓冲区,它可以在Java应用程序的堆内存之外分配内存,这个内存区域可以被操作系统直接访问,从而避免了数据的多次拷贝。Java NIO库是Java提供的一种基于通道和缓冲区的IO操作方式,它可以通过零拷贝技术来提高数据传输的性能和效率。

下面是一个简单的Java程序,演示了如何使用零拷贝技术来实现文件的快速复制:

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class ZeroCopyDemo {
    public static void main(String[] args) {
        try {
            // 打开输入文件和输出文件的通道
            FileInputStream input = new FileInputStream("input.txt");
            FileOutputStream output = new FileOutputStream("output.txt");
            FileChannel inputChannel = input.getChannel();
            FileChannel outputChannel = output.getChannel();

            // 分配直接内存缓冲区
            ByteBuffer buffer = ByteBuffer.allocateDirect(1024);

            // 从输入通道读取数据,并直接写入输出通道
            while (inputChannel.read(buffer) != -1) {
                buffer.flip();
                outputChannel.write(buffer);
                buffer.clear();
            }

            // 关闭通道和文件流
            inputChannel.close();
            outputChannel.close();
            input.close();
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个程序中,我们首先打开输入文件和输出文件的通道,并分配一个直接内存缓冲区。然后,我们从输入通道读取数据,并将数据直接写入输出通道中,这个过程中只涉及到一次数据拷贝操作,从而提高了程序的性能和效率。最后,我们关闭通道和文件流。

需要注意的是,零拷贝技术并不是适用于所有的场景,它主要适用于大数据量的数据传输,例如文件的快速复制和网络数据的传输等。在一些小数据量的场景中,零拷贝技术可能会带来额外的性能开销,需要根据具体的场景来选择是否使用零拷贝技术。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/539182.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库迁移 | 拥抱国产化数据库openGauss

Squids DBMotion再添新库同步能力,本期增加了对openGauss数据库的同步支持。 openGauss数据库是一款开源关系型数据库管理系统,采用木兰宽松许可证v2发行。openGauss内核深度融合华为在数据库领域多年的经验,结合企业级场景需求,持…

PFTL101B 20KN 3BSE004203R1主要介绍ACS380 Modbus通讯功能

​ PFTL101B 20KN 3BSE004203R1ABB系统优化船舶性能、效率和可持续性 根据经合组织的一份报告,货物和人员的海上运输是全球经济活动的重要驱动力,到2050年将增加两倍。据国际海事组织(IMO)称,这一增长将导致该行业的温…

Hi3861 移植 LVGL

一、前言 给 Hi3861 适配了硬件 spi ,master 模式下最高 spi 速率可以达到 40M,用来驱动 oled 屏幕。 适配过程遇到了一个芯片bug,困扰了很久,clk 管脚驱动能力差,需要外接一个上拉电阻才能正常运行。适配完成移植 lvg…

k8s系列(五)——资源控制器

k8s系列五——资源控制器 控制器的必要性 自主式Pod对象由调度器调度到目标工作节点后即由相应节点上的kubelet负责监控其容器的存活状态,容器主进程崩溃后,kubelet能够自动重启相应的容器。但对出现非主进程崩溃类的容器错误却无从感知,这…

阿里下放自动驾驶,汽车业务是个坑,或是时候探讨下一个乐视了

阿里发布公告指达摩院自动驾驶团队将全部并入菜鸟集团,虽然并没有说关闭自动驾驶业务,但是自动驾驶业务已不再是阿里看重的业务,导致如此结果在于当前汽车行业发生的重大变化。 一、传统汽车开始发力 今年4月份的新能源汽车企业销量排名数据显…

配置gitee ssh免密拉取代码-唯一客服系统文档中心

Gitee 我们的客服系统代码托管于Gitee私有仓库默认情况下只用于开发者自我代码管理,不对外公布。如果你也是放在私有仓库进行托管,可以如下配置免密操作。 部署公钥免密拉取代码 部署公钥允许以只读的方式访问仓库,主要用于仓库在生产服务器的…

即时通讯在线聊天APP开发解决方案

即时通讯是目前移动端最为流行的通讯方式,各种各样的即时通讯软件也层出不穷;服务提供商也提供了越来越丰富的通讯服务功能,打造一个实时通信系统,允许两人或多人使用网络实时的传递文字消息、文件、语音与视频交流。今天河北领行…

Excel中时间戳与标准日期格式的互相转换

背景 在excel中将13位毫秒级别的时间戳转换为标准的日期格式(yyyy-mm-dd hh:mm:ss.000)&#xff0c;使用如下模板 TEXT(<source_cell>/1000/8640070*36519,"yyyy-mm-dd hh:mm:ss.000") 在excel中将10位秒级别的时间戳转换为标准的日期格式(yyyy-mm-dd hh:mm:ss…

每日学习记录

GDB调试 首先是安装&#xff0c;以及普通的一些命令&#xff0c;重点是如何打断点 调试多进程和多线程 不同的gdb版本可能不是很支持&#xff0c;需要用比较新的版本>8.3 多进程 fork()函数创建一个一模一样的进程正常来说&#xff0c;同一个执行文件&#xff0c;gdb只…

使用 CNN 进行面部情绪识别

面部表情是人类之间交流的重要方式。 在人工智能研究中&#xff0c;深度学习技术已成为增强人机交互的强大工具。心理学中面部表情和情绪的分析和评估涉及评估预测个人或群体情绪的决定。 本研究旨在开发一种能够使用卷积神经网络&#xff08;CNN&#xff09;算法和特征提取技术…

【Java每日一练】总目录(2023.3.11~5.18)共69篇

2023.3.11~2023.5.18 连载两个多月共69篇&#xff0c;暂停更 Java 2023.05 2023.5.11-2023.5.18 20230518 1. 移除链表元素 &#x1f31f; 2. 跳跃游戏 II &#x1f31f;&#x1f31f; 3. 复原 IP 地址 &#x1f31f;&#x1f31f; 20230517 1. 存在重复元素 &#x…

chatgpt赋能Python-pycharm添加库

Pycharm添加库 – 提高Python编程效率的绝佳利器 Pycharm是一款强大的Python IDE&#xff0c;为广大Python开发人员提供了高度集成化的开发环境。通过Pycharm&#xff0c;我们可以充分利用各种强大的开发工具来简化开发流程&#xff0c;提高编程效率。其中一项重要的功能就是添…

SciPy库(一)常数与特殊函数与插值

一、概述 SciPy是一个开源的Python科学计算库&#xff0c;它建立在NumPy之上&#xff0c;提供了许多有用的科学计算功能。SciPy包括各种科学计算模块&#xff0c;如线性代数、优化、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理等。SciPy库的主要特点是其高效性和…

突然放大,Midjourney 来中国了!

突然放大&#xff0c;Midjourney 来中国了&#xff01; 一、 Midjourney内测版本的推出 Midjourney&#xff0c;一款新颖的 AI 视觉艺术平台&#xff0c;近日在中国开放了内测版。这个内测版本在 QQ 频道上进行&#xff0c;每周一和周五的 18:00 开放入口&#xff0c;人数一旦满…

家里宽带申请公网 IP(二)

来源&#xff1a;公众号【鱼鹰谈单片机】 作者&#xff1a;鱼鹰Osprey ID &#xff1a;emOsprey 在之前的《家里宽带搞个服务器&#xff0c;YYDS&#xff08;一&#xff09;》笔记中大概介绍了&#xff0c;因为现有的 IPv4 的地址资源枯竭&#xff0c;导致大部分网络都是局域…

中国系统正式发声!所有用户永久免费,网友:再见了,CentOS!

点关注公众号&#xff0c;回复“1024”获取2TB学习资源&#xff01; 如果说&#xff1a;没有操作系统会怎么样&#xff1f; 对于个PC来说&#xff0c;无论是台式机、笔记本、平板等等&#xff0c;一切都变的一无是处&#xff0c;这些硬件对我们来说&#xff0c;和一堆废铁没什么…

手把手写一个简单IOC(基于XML配置文件)

目录 创建模块 准备测试阶段测试用的Bean 编写ApplicationContext接口 编写ClassPathXmlApplicationContext 确定采用Map集合存储Bean 解析配置文件实例化所有Bean 解析配置文件实例化所有Bean 测试阶段1(实例化bean) Bean的属性赋值 测试阶段2(为bean对象进行赋值)…

初阶数据结构——栈和队列习题

目录 括号匹配问题思路代码 用队列实现栈思路注意点代码 用栈实现队列思路代码 设计循环队列思路数组实现代码链表实现代码 括号匹配问题 OJ链接 思路 是左括号则入栈&#xff0c;是右括号则出栈然后两两比较 代码 #include<stdio.h> #include<stdlib.h> #i…

洛谷P1157详解(两种解法,一看就会)

一、问题引出 组合的输出 题目描述 排列与组合是常用的数学方法&#xff0c;其中组合就是从 n n n 个元素中抽出 r r r 个元素&#xff08;不分顺序且 r ≤ n r \le n r≤n&#xff09;&#xff0c;我们可以简单地将 n n n 个元素理解为自然数 1 , 2 , … , n 1,2,\dot…

chatgpt赋能Python-pycharm桌面图标变白

PyCharm是一个非常流行的Python集成开发环境&#xff0c;它可以帮助Python开发人员更快更高效地编写代码。但是&#xff0c;有些用户可能会遇到一个问题&#xff1a;他们的PyCharm桌面图标突然变成了白色&#xff0c;而不是原来的彩色图标。在这篇文章中&#xff0c;我将详细介…