Java基础-零拷贝技术应用案例
Java基础-零拷贝技术应用案例
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
零拷贝技术在Hadoop生态圈中很多组件得到应用,典型的比如kafka组件,它就很成功的应用了零拷贝技术,那么究竟什么是零拷贝技术呢?以及零拷贝技术和传统的拷贝技术有什么差异呢?还有零拷贝有什么缺陷呢?接下来,本篇博客会跟你一起验证这些问题!
一.传统拷贝
1>.Java中的传统拷贝
答:正常拷贝先将文件从磁盘交换到系统(内核)空间,再从内核空间交换到user空间,再从user空间交换到内核空间,最后从内核空间交换到目的缓冲区.。接下里我画一张草图来进行解析说明,如下:

2>.传统拷贝案例展示
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.zeroCopy; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel; public class Test2 {
public static void main(String[] args) throws Exception{
File input = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjieJava.rar");
File tcOutput = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjieJava2.rar"); traditionalCopy(input,tcOutput);
} public static void traditionalCopy(File input,File output) throws Exception{
long start = System.currentTimeMillis();
RandomAccessFile rafRead = new RandomAccessFile(input,"rw");
RandomAccessFile rafWrite = new RandomAccessFile(output,"rw");
byte[] buf = new byte[1024];
int len ;
while ((len = rafRead.read(buf)) != -1 ){
rafWrite.write(buf,0,len);
}
rafRead.close();
rafWrite.close();
long end = System.currentTimeMillis();
System.out.println("traditionalCopy 用时为:" + (end - start));
}
} /*
traditionalCopy 用时为:5399
*/
二.零拷贝
1>.什么是零拷贝
答:零拷贝是直接从磁盘交换到内核空间,从内核空间直接输出到目的缓冲区。接下里我画一张草图来进行解析说明,如下:

2>.零拷贝案例展示
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.zeroCopy; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel; public class Test2 {
public static void main(String[] args) throws Exception{
File input = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjieJava.rar");
File zcOutput = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjieJava3.rar"); ZeroCopy(input,zcOutput);
} public static void ZeroCopy(File input,File output) throws Exception {
long start = System.currentTimeMillis();
//文件输出
FileInputStream fis = new FileInputStream(input);
//源文件通道
FileChannel srcFC = fis.getChannel();
//输出流
FileOutputStream fos = new FileOutputStream(output);
//输出文件通道
FileChannel destFC = fos.getChannel();
srcFC.transferTo(0 , input.length() , destFC) ;
long end = System.currentTimeMillis();
System.out.println("ZeroCopy 用时为:" + (end - start));
}
} /*
ZeroCopy 用时为:588
*/
三.测试零拷贝方式和常规拷贝方式性能对比
测试零拷贝和传统拷贝的性能我们只需要加一个计时功能即可,具体实现代码如下:
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.zeroCopy; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel; public class Test2 {
public static void main(String[] args) throws Exception{
File input = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjieJava.rar");
File tcOutput = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjieJava2.rar");
File zcOutput = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjieJava3.rar"); traditionalCopy(input,tcOutput);
ZeroCopy(input,zcOutput);
} public static void traditionalCopy(File input,File output) throws Exception{
long start = System.currentTimeMillis();
RandomAccessFile rafRead = new RandomAccessFile(input,"rw");
RandomAccessFile rafWrite = new RandomAccessFile(output,"rw");
byte[] buf = new byte[1024];
int len ;
while ((len = rafRead.read(buf)) != -1 ){
rafWrite.write(buf,0,len);
}
rafRead.close();
rafWrite.close();
long end = System.currentTimeMillis();
System.out.println("traditionalCopy 用时为:" + (end - start));
} public static void ZeroCopy(File input,File output) throws Exception {
long start = System.currentTimeMillis();
//文件输出
FileInputStream fis = new FileInputStream(input);
//源文件通道
FileChannel srcFC = fis.getChannel();
//输出流
FileOutputStream fos = new FileOutputStream(output);
//输出文件通道
FileChannel destFC = fos.getChannel();
srcFC.transferTo(0 , input.length() , destFC) ;
long end = System.currentTimeMillis();
System.out.println("ZeroCopy 用时为:" + (end - start));
}
} /*
traditionalCopy 用时为:5286
ZeroCopy 用时为:1986
*/
执行以上代码后,需要去响应目录检查是否拷贝成功,验证结果如下:

四.零拷贝细节
1>.Linux中的零拷贝
零拷贝技术的发展很多样化,现有的零拷贝技术种类也非常多,而当前并没有一个适合于所有场景的零拷贝技术的出现。对于 Linux 来说,现存的零拷贝技术也比较多,这些零拷贝技术大部分存在于不同的 Linux 内核版本,有些旧的技术在不同的 Linux 内核版本间得到了很大的发展或者已经渐渐被新的技术所代替。Linux 中的零拷贝技术主要有下面这几种:
直接 I/O:
对于这种数据传输方式来说,应用程序可以直接访问硬件存储,操作系统内核只是辅助数据传输:这类零拷贝技术针对的是操作系统内核并不需要对数据进行直接处理的情况,数据可以在应用程序地址空间的缓冲区和磁盘之间直接进行传输,完全不需要 Linux 操作系统内核提供的页缓存的支持。
在数据传输的过程中,避免数据在操作系统内核地址空间的缓冲区和用户应用程序地址空间的缓冲区之间进行拷贝。
有的时候,应用程序在数据进行传输的过程中不需要对数据进行访问,那么,将数据从 Linux 的页缓存拷贝到用户进程的缓冲区中就可以完全避免,传输的数据在页缓存中就可以得到处理。在某些特殊的情况下,这种零拷贝技术可以获得较好的性能。Linux 中提供类似的系统调用主要有 mmap(),sendfile() 以及 splice()。
对数据在 Linux 的页缓存和用户进程的缓冲区之间的传输过程进行优化。
该零拷贝技术侧重于灵活地处理数据在用户进程的缓冲区和操作系统的页缓存之间的拷贝操作。这种方法延续了传统的通信方式,但是更加灵活。在 Linux 中,该方法主要利用了写时复制技术。
2>.零拷贝缺陷
零拷贝也有自己的缺陷,当它拷贝的文件大于2G时,就无法完整实现拷贝过程!比如你拷贝一个4G文件左右,它最终的结果是只能拷贝2G大小的文件。我测试使用CentOS官方镜像进行拷贝!测试代码如下:
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.zeroCopy; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel; public class Test2 {
public static void main(String[] args) throws Exception{
RandomAccessFileTest();
ZeroCopy();
} public static void RandomAccessFileTest() throws Exception{
long start = System.currentTimeMillis();
File input = new File("D:\\VMwareworkStation\\ISO\\CentOS-7-x86_64-DVD-1511.iso");
File output = new File("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjie_CentOS7.iso");
RandomAccessFile rafRead = new RandomAccessFile(input,"rw");
RandomAccessFile rafWrite = new RandomAccessFile(output,"rw"); byte[] buf = new byte[1024]; int len ;
while ((len = rafRead.read(buf)) != -1 ){
rafWrite.write(buf,0,len);
} rafRead.close();
rafWrite.close(); long end = System.currentTimeMillis();
System.out.println("RandomAccessFile 用时为:" + (end - start));
} public static void ZeroCopy() throws Exception {
long start = System.currentTimeMillis(); File input = new File("D:\\VMwareworkStation\\ISO\\CentOS-7-x86_64-DVD-1511.iso") ;
//文件输出
FileInputStream fis = new FileInputStream(input);
//源文件通道
FileChannel srcFC = fis.getChannel();
//输出流
FileOutputStream fos = new FileOutputStream("D:\\BigData\\JavaSE\\yinzhengjieData\\yinzhengjie_CentOS7_1.iso");
//输出文件通道
FileChannel destFC = fos.getChannel();
srcFC.transferTo(0 , input.length() , destFC) ;
System.out.println(System.currentTimeMillis() - start);
long end = System.currentTimeMillis();
System.out.println("ZeroCopy 用时为:" + (end - start));
}
} /*
RandomAccessFile 用时为:46436
ZeroCopy 用时为:1275 */
以上代码执行结果如下:(数据并没有完整拷贝!!!)

Java基础-零拷贝技术应用案例的更多相关文章
- 【Netty技术专题】「原理分析系列」Netty强大特性之ByteBuf零拷贝技术原理分析
零拷贝Zero-Copy 我们先来看下它的定义: "Zero-copy" describes computer operations in which the CPU does n ...
- Linux 零拷贝技术
简介 零拷贝(zero-copy)技术可以减少数据拷贝和共享总线操作的次数,消除通信数据在存储器之间不必要的中间拷贝过程,有效地提高通信效率,是设计高速接口通道.实现高速服务器和路由器的关键技术之一. ...
- java的零拷贝机制
转:https://blog.csdn.net/zhouhao88410234/article/details/77574689?fps=1&locationNum=9 为何要懂零拷贝原理?因 ...
- Linux零拷贝技术,看完这篇文章就懂了
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复 「1024」 即可领取,欢迎大家关注,二维码文末可以扫. 本文讲解 ...
- Linux零拷贝技术
本文转载自Linux零拷贝技术 导语 本文讲解 Linux 的零拷贝技术,云计算是一门很庞大的技术学科,融合了很多技术,Linux 算是比较基础的技术,所以,学好 Linux 对于云计算的学习会有比较 ...
- 操作系统IO之零拷贝技术
磁盘可以说是计算机系统最慢的硬件之一,读写速度相差内存 10 倍以上,所以针对优化磁盘的技术非常的多,比如零拷贝.直接 I/O.异步 I/O 等等,这些优化的目的就是为了提高系统的吞吐量,另外操作系统 ...
- Linux 中的零拷贝技术,第 2 部分
技术实现 本系列由两篇文章组成,介绍了当前用于 Linux 操作系统上的几种零拷贝技术,简单描述了各种零拷贝技术的实现,以及它们的特点和适用场景.第一部分主要介绍了一些零拷贝技术的相关背景知识,简要概 ...
- Linux 中的零拷贝技术,第 1 部分
概述 本系列由两篇文章组成,介绍了当前用于 Linux 操作系统上的几种零拷贝技术,简单描述了各种零拷贝技术的实现,以及它们的特点和适用场景.本文是本系列文章的第一部分,主要是介绍一些零拷贝技术的相关 ...
- Linux中的零拷贝技术
转载:https://www.jianshu.com/p/fad3339e3448 引文## 在写一个服务端程序时(Web Server或者文件服务器),文件下载是一个基本功能.这时候服务端的任务是: ...
随机推荐
- 【HNOI2017】礼物
题面 题解 显然两个手环只需要一个的亮度增加\(c \in [-m, m]\)和原题是等价的. 于是可以写成这样一个公式: \[ \sum_{i = 1} ^ n(x_i - y_{i+k} + c) ...
- python 函数学习
print dic.items() #[('a', 'hello'), ('c', 'you'), ('b', 'how')] print dic.iteritems() #<dictionar ...
- php faker 库填充数据
Generating Fake Data in PHP with Faker 时间 2016-01-28 07:13:00 Wern Ancheta 原文 http://wern-ancheta.c ...
- linux下SpringBoot Jar包自启脚本配置
今天整理服务器上SpringBoot项目发现是自启的,于是想看看实现.翻看离职同事的交接文档发现一个***.service文件内容如下 [Unit] Description=sgfront After ...
- spring boot 2.0 源码分析(二)
在上一章学习了spring boot 2.0启动的大概流程以后,今天我们来深挖一下SpringApplication实例变量的run函数. 先把这段run函数的代码贴出来: /** * Run the ...
- C++学习 内存模型和名称空间
1.单独编译 C++鼓励程序员将组件函数放在独立的文件中,如果只修改了一个文件,则可以只重新编译该文件,然后将它与其他文件的编译版本链接. 一般非常有用的组织程序的策略是把程序分成三部分: 头文件:包 ...
- PAT-1010 Radix
1010 Radix (25 分) Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 1 ...
- Linux 第六周实验
姬梦馨 原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.进程控制块PCB——task_st ...
- Spring scope注解
Spring注解中@scope默认为单例模式(singleton) 设置写法@scope("") 1.singleton单例模式 全局有且仅有一个实例 2.prototype原型模 ...
- BAE静态文件问题
这几天想在bae上架一个自己的博客,但是老是访问不到静态文件文件,都要没有办法了,最后看了这篇博客,受到了启发,知道了问题所在: 我自己的原始的app.conf的配置如下: handlers: - u ...