1 分钟看穿零拷贝技术,看不懂你打我

2024-02-25 16:38

本文主要是介绍1 分钟看穿零拷贝技术,看不懂你打我,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Photo By Instagram sooyaaa

问题 15

上一期中我们一起讨论了 Java 的三大 IO 模型,说到其中的 Non-Blocking IO 就不得不提零拷贝技术,你知道零拷贝技术吗?

我的答案

想要弄清楚什么是零拷贝,首先得明确一个问题,这里的拷贝指的是什么?我们这里所描述的 拷贝 指的是在应用程序中将文件从 A 拷贝到 B,其中的 A 和 B 可以是电脑上的磁盘文件,也可以是网络中的文件。像这样的拷贝操作在操作系统中经历了复杂的操作,首先应用程序发起读取文件操作,读取到文件后又发起写入文件操作或者写到网络中去。

传统的数据传输

了解传统数据传输之前,我们要明确用户态和内核态 2 个概念:

用户态 是非特权执行状态,该状态下运行的程序被操作系统禁止进行一些危险操作,例如写入系统配置文件,杀死其他用户进程,重启系统,不可直接访问硬件设备。

内核态 是高级别特权执行状态,运行在该状态下的程序通常为操作系统程序,具有高的特权级别,拥有访问设备的所有权限。

读、写操作,在我们看来是一个完整的操作,其实在操作系统内部将读操作又进行了细化拆分。

首先操作系统需要从用户态切换到内核态,在内核态将文件内容从磁盘读取到内核空间缓冲区中。

然后切换到用户态,将文件内容从内核空间缓冲区读取到用户空间。

而写操作正好是一个逆向的过程,程序需要先将文件内容写到内核空间缓冲区,然后从用户态切换到内核态,再将内容写到磁盘里,最后切换回用户态。图示为如下:

聪明的宝宝肯定注意到了,这其中涉及到了 4 次的上下文切换和 4 次的数据拷贝操作,其中磁盘与内核态进行的拷贝操作应用了 DMA 技术(全称 Direct Memory Access,它是一项由硬件设备支持的 IO 技术,应用这项技术可以更好的利用 CPU 资源,在此期间 CPU 可以去做其他事情),而内核态缓冲区到应用程序传输数据需要 CPU 的参与,在此期间 CPU 不能做其他工作。

mmap 提升拷贝性能

mmap 是一种内存映射的方法,它可以将磁盘上的文件映射进内存。用户程序可以直接访问内存即可达到访问磁盘文件的效果,这种数据传输方法的性能高于将数据在内核空间和用户之间来回拷贝操作,通常用于高性能要求的应用程序中。

因为用户态和内核态的上下文切换以及 CPU 数据拷贝是耗时的操作,所以可以考虑减少数据传输过程中的上下文切换和繁多的 CPU 拷贝数据操作,从而来提升数据传输性能。采用 mmap 来代替 read 系统调用可以有效减少内核空间到用户空间之间的 CPU 拷贝数据操作,于是就诞生了如下的工作情形:

观察如上拷贝示意图,我们可以发现此时上下文切换操作缩减到了 2 次,应用程序发起拷贝操作后切换到内核态,数据直接在内核态完成传输而不需要拷贝到用户态,但是此处仍然进行了 3 次拷贝操作,其中还包含一次耗时的 CPU 拷贝操作。别着急,接下来我们看看终极版零拷贝。

零拷贝技术

我们知道 DMA 技术是高效的,因此只要去除掉 CPU 拷贝操作即可大大的提升性能。在 Linux 内核 2.1 版本中引入了 sendfile 系统调用,采用这种方式后内核态的缓冲区之间不再进行 CPU 拷贝操作,只需要将源数据的地址和长度告诉目标缓冲区,然后直接采用 DMA 技术将数据传输到目的地,如下图示:

如上采用 sendfile 已经剔除了所有耗时的 CPU 拷贝操作,相比于传统的数据拷贝操作性能更高,这就是所谓的零拷贝技术。

Java 中的零拷贝

使用传统的文件拷贝方式在 Java 你会看到如下样板代码:

try (FileInputStream fis = new FileInputStream("sourceFile.txt");FileOutputStream fos = new FileOutputStream("targetFile.txt")) {byte datas[] = new byte[1024*8];int len = 0;while((len = fis.read(datas)) != -1){fos.write(datas, 0, len);}
}

使用如上方式进行文件拷贝的内在执行原理就如我们开头的介绍的那样,经过了多次用户态和内核态的切换,并且伴随着耗时的 CPU 拷贝操作,可想而知在遇到大文件拷贝时候效率会比较低下,此时可以考虑使用零拷贝技术。

在Java 1.4 中, FileChannel 的 transferTo 方法即引入了零拷贝技术,让我们来一起看一下,如何使用它来提升性能吧。

RandomAccessFile sourceFile = new RandomAccessFile("sourceFile.txt", "rw");
FileChannel fromChannel = sourceFile.getChannel();RandomAccessFile targetFile = new RandomAccessFile("targetFile.txt", "rw");
FileChannel toChannel = targetFile.getChannel();fromChannel.transferTo(0, fromChannel.size(), toChannel);

如上我们首先获取 FilleChannel,然后调用 FileChannel 的 transferTo 方法即可实现零拷贝操作。内在执行原理就是使用 sendfile 系统调用,剔除了耗时的 CPU 拷贝操作,同时用户态和内核态的上下文切换也是最少的,当你遇到文件拷贝的性能问题时,你可以考虑一下 FilleChannel。

FileChannel 中还提供了其他的方法,例如 transferFrom 方法,感兴趣的小伙伴可以自己尝试一下。

以上即为本期的主题,小伙伴们是否有疑问呢?欢迎留言和我讨论。

金三银四啦,每天一道题目,让 offer 来得简单点。

感谢你的阅读,我为你准备了一份《高级 Java 面试指南》,点击在看,关注公众号,回复 "礼物" 获取。

武汉加油!中国加油!

这篇关于1 分钟看穿零拷贝技术,看不懂你打我的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/746069

相关文章

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

Java中ArrayList的8种浅拷贝方式示例代码

《Java中ArrayList的8种浅拷贝方式示例代码》:本文主要介绍Java中ArrayList的8种浅拷贝方式的相关资料,讲解了Java中ArrayList的浅拷贝概念,并详细分享了八种实现浅... 目录引言什么是浅拷贝?ArrayList 浅拷贝的重要性方法一:使用构造函数方法二:使用 addAll(

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

金融业开源技术 术语

金融业开源技术  术语 1  范围 本文件界定了金融业开源技术的常用术语。 本文件适用于金融业中涉及开源技术的相关标准及规范性文件制定和信息沟通等活动。

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时

系统架构设计师: 信息安全技术

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 系统架构设计师: 信息安全技术前言信息安全的基本要素:信息安全的范围:安全措施的目标:访问控制技术要素:访问控制包括:等保

前端技术(七)——less 教程

一、less简介 1. less是什么? less是一种动态样式语言,属于css预处理器的范畴,它扩展了CSS语言,增加了变量、Mixin、函数等特性,使CSS 更易维护和扩展LESS 既可以在 客户端 上运行 ,也可以借助Node.js在服务端运行。 less的中文官网:https://lesscss.cn/ 2. less编译工具 koala 官网 http://koala-app.

软件架构模式:5 分钟阅读

原文: https://orkhanscience.medium.com/software-architecture-patterns-5-mins-read-e9e3c8eb47d2 软件架构模式:5 分钟阅读 当有人潜入软件工程世界时,有一天他需要学习软件架构模式的基础知识。当我刚接触编码时,我不知道从哪里获得简要介绍现有架构模式的资源,这样它就不会太详细和混乱,而是非常抽象和易

Spring的设计⽬标——《Spring技术内幕》

读《Spring技术内幕》第二版,计文柯著。 如果我们要简要地描述Spring的设计⽬标,可以这么说,Spring为开发者提供的是⼀个⼀站式的轻量级应⽤开发框架(平台)。 作为平台,Spring抽象了我们在 许多应⽤开发中遇到的共性问题;同时,作为⼀个轻量级的应⽤开发框架,Spring和传统的J2EE开发相⽐,有其⾃⾝的特点。 通过这些⾃⾝的特点,Spring充分体现了它的设计理念:在

java线程深度解析(六)——线程池技术

http://blog.csdn.net/Daybreak1209/article/details/51382604 一种最为简单的线程创建和回收的方法: [html]  view plain copy new Thread(new Runnable(){                @Override               public voi