java-nio之zero copy深入分析
对于所有的io操作,底层一定是调用操作系统的api来进行读写。受限于不同的操作系统,操作方式一定是有差异的。以下read和write操作,可以看做服务器从磁盘硬件上读取文件数据,然后通过socket发送给客户端的流程。
传统io服务端对客户端的传输

对于读操作:jvm虚拟机一定会发送一个read()操作系统级别的方法,由此会产生一个上下文的切换,从程序所在的用户空间切换至系统的内核空间,内核空间向磁盘空间请求数据,通过DMA直接内存访问的方式将数据读取到内核空间缓冲区,此时用户空间是无法直接使用的,所以下面会将这份缓冲数据原封不动的拷贝到用户空间,至此read操作就结束。期间有两次上下文的切换,和两次数据的拷贝
对于写操作:将文件读取之后需要发送给远端socket客户端。同样调用系统级别的write方法,需要将上述读到的用户空间的数据原封不动的拷贝到内核上的socket缓冲区,然后DMA 引擎将数据从该缓冲区传到协议引擎,这一次拷贝独立地、异步地发生 。
对于这种io的操作,用户空间只是作为一个中转站,会和内核空间有不必要的上下文切换和数据之间的拷贝
操作系统对于io的一种优化方式
对于优化方式,需要系统直接的支持,jvm是无法提供任何的帮助。对于传统的linux、unix等操作系统是支持的

对于读写操作:用户空间向操作系统发送sendfile()方法,后续的操作只会在内核空间完成。对于所有的读写操作将只会有两次的用户空间和内核空间切换,这种操作称为操作系统意义上的零拷贝。同样的后续会通过DMA的方式向磁盘空间读取数据,读到内核空间的缓冲区,然后将这部分数据写到socket缓冲区,然后通过socket缓冲区向客户端发送数据,完成之后向内核空间然后向用户空间发送数据。相比于第一种方式有了极大的改善。
io的进一步优化方式

相对于上一种方案,内核空间会将数据复制一份到socket缓冲区,因为对于DMA直接内存访问的机制,希望内存地址是连续的,当然buffer的地址是连续的,因此会多一步拷贝到socket缓冲区,如果操作系统支持buffer中的scatter/gather,那么我们就能够有效的避免这种问题。可以通过scatter/gather的方式来读取数据到内核空间然后直接进行后续的写操作,从而减少中间的一步拷贝。
最佳的方式

通过DMA的方式拷贝数据到内核缓冲区,将对应的文件描述符写到socket buffer中,包含了内核的缓冲区的地址和数据长度,并不需要将数据拷贝到socket buffer中,只用存文件描述符。最后协议引擎发送数据的时候,从kernel buffer和socket buffer里面读取数据,对于kernel buffer是真实数据的读取,而对于socket buffer是文件描述符的读取,通过gather操作最终一起发送给客户端
很多的web应用程序都支持零拷贝,比如apache和tomcat,Java中提供的nio的方式是通过transferTo来实现
对于我们上面所述的所有方式,用户是无法对文件进行一定的操作。我们可以通过内存映射在中间过程来对文件进行一定的操作:

参考:
http://xcorpion.tech/2016/09/10/It-s-all-about-buffers-zero-copy-mmap-and-Java-NIO/
https://www.ibm.com/developerworks/library/j-zerocopy/
http://www.linuxjournal.com/article/6345?page=0,0
java-nio之zero copy深入分析的更多相关文章
- Java NIO使用及原理分析(1-4)(转)
转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...
- 攻破JAVA NIO技术壁垒
转载自攻破JAVA NIO技术壁垒 概述 NIO主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector.传统IO基于字节流和字符流进行操作,而NIO基于Channel和 ...
- Java Se : Java NIO(服务端)与BIO(客户端)通信
Java目前有三种IO相关的API了,下面简单的说一下: BIO,阻塞IO,最常用的Java IO API,提供一般的流的读写功能.相信学习Java的人,都用过. NIO,非阻塞IO,在JDK1.4中 ...
- Java NIO 基础
Java在JDK1.4中引入了 java.nio 类库,为Java进军后端Server和中间件开发打开了方便之门. 一般而言,这里的 nio 代表的是 New I/O,但是从实质上来说,我们可以将其理 ...
- Java NIO教程 文件系统
在NIO.2的文件系统中,Path是一切操作的基础.Path准确来说,代表着文件系统中的位置.可以代表一个目录(也就是通常所说的文件夹),也可以代表一个文件. 在新文件系统中,还有一个不得不说的就是F ...
- Java NIO教程 MappedByteBuffer
之前跟大家说过,要讲MappedByteBuffer,现在我来履行承诺了. 首先从大体上讲一下MappedByteBuffer究竟是什么.从继承结构上来讲,MappedByteBuffer继承自Byt ...
- JAVA NIO是什么(zz)
JAVA NIO是什么? 1. 基本 概念 IO 是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成. 所有语言运行时系 ...
- Java NIO、NIO.2学习笔记
相关学习资料 http://www.molotang.com/articles/903.html http://www.ibm.com/developerworks/cn/education/java ...
- 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor
开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...
- Java Nio 多线程网络下载
--> 默认最多50个线程 同一文件下载失败延迟超过30秒就结束下载 --> 下载5分钟超时时间,假设5分钟内未下载完就结束下载 --> 依赖 commons-httpclient ...
随机推荐
- java中static,final,private方法的继承多态问题
父类中的final private方法不能被继承,父类中的static方法可以被继承,但是不能重写,这三者都属于前期绑定,java中除了这三种以及构造方法之外剩下的都是后期绑定(运行是绑定). 当父 ...
- Qt5编译oracle驱动教程
我们都知道oracle数据库的强大,并且好多企业或者教学用到数据库时都会推荐使用.但是Qt因为版权问题没有封装oracle数据库专用驱动,网上也有一大堆说法和教程,但是或多或少的都有问题.下面废话不多 ...
- 卡在 构建 gradle 项目信息
之所以卡死是因为Android Studio在初次构建的时候,会联网进行gradle目录的更新操作.断网之后就不会去主动更新了. 断网. 打开项目. 把 gradle 改成 使用当地. ======= ...
- BZOJ.4032.[HEOI2015]最短不公共子串(DP 后缀自动机)
题目链接 1.求A的最短子串,它不是B的子串. 子串是连续的,对B建SAM,枚举起点,在SAM上找到第一个无法匹配点即可.O(n)用SAM能做吗..开始想错了. 2.求A的最短子串,它不是B的子序列. ...
- 什么是 "use strict"? 使用它的好处和坏处分别是什么?
ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode).顾名思义,这种模式使得Javascript在更严格的条件下运行. 设立"严格模式&q ...
- centos 7.2 安装mysql 修改 初始密码
# /etc/init.d/mysqld stop # mysqld_safe --user=mysql --skip-grant-tables --skip-networking &# my ...
- WebMvcConfigurerAdapter已经过时的问题解决
spring 5开始已经废弃WebMvcConfigurerAdapter,替代的是WebMvcConfigurer接口. 参考: https://blog.csdn.net/lenkvin/arti ...
- HDU 3974 Assign the task(简单线段树)
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- STM32F4: Generating parallel signals with the FSMC
STM32F4: Generating parallel signals with the FSMC The goal: The memory controller can be used to ge ...
- MDK5 and STM32Cube
D:\Workspace\........\RTE\Device>STM32CubeMX.exe -s project.script -tpl_path C:\Keil5\ARM\Pack\Ke ...