对于所有的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深入分析的更多相关文章

  1. Java NIO使用及原理分析(1-4)(转)

    转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...

  2. 攻破JAVA NIO技术壁垒

    转载自攻破JAVA NIO技术壁垒 概述 NIO主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector.传统IO基于字节流和字符流进行操作,而NIO基于Channel和 ...

  3. Java Se : Java NIO(服务端)与BIO(客户端)通信

    Java目前有三种IO相关的API了,下面简单的说一下: BIO,阻塞IO,最常用的Java IO API,提供一般的流的读写功能.相信学习Java的人,都用过. NIO,非阻塞IO,在JDK1.4中 ...

  4. Java NIO 基础

    Java在JDK1.4中引入了 java.nio 类库,为Java进军后端Server和中间件开发打开了方便之门. 一般而言,这里的 nio 代表的是 New I/O,但是从实质上来说,我们可以将其理 ...

  5. Java NIO教程 文件系统

    在NIO.2的文件系统中,Path是一切操作的基础.Path准确来说,代表着文件系统中的位置.可以代表一个目录(也就是通常所说的文件夹),也可以代表一个文件. 在新文件系统中,还有一个不得不说的就是F ...

  6. Java NIO教程 MappedByteBuffer

    之前跟大家说过,要讲MappedByteBuffer,现在我来履行承诺了. 首先从大体上讲一下MappedByteBuffer究竟是什么.从继承结构上来讲,MappedByteBuffer继承自Byt ...

  7. JAVA NIO是什么(zz)

    JAVA NIO是什么? 1.   基本 概念 IO 是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成. 所有语言运行时系 ...

  8. Java NIO、NIO.2学习笔记

    相关学习资料 http://www.molotang.com/articles/903.html http://www.ibm.com/developerworks/cn/education/java ...

  9. 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor

    开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...

  10. Java Nio 多线程网络下载

    --> 默认最多50个线程 同一文件下载失败延迟超过30秒就结束下载 --> 下载5分钟超时时间,假设5分钟内未下载完就结束下载 --> 依赖 commons-httpclient ...

随机推荐

  1. 027.Zabbix的定期备份

    一 数据库备份及恢复 1.1:全库备份 [root@zabbix01 ~]# mysqldump -uroot -p123456 --opt zabbix > zabbix.sql [root@ ...

  2. 011.Zabbix的拓扑创建

    一 Map简介 Map的作用是将各种设备用网络拓扑图的方式展示,在Zabbix中,拓扑的展示通过手动方式添加. 二 Map的添加 2.1 添加Map的背景图 #在添加Map之前可谓Map添加一个背景图 ...

  3. 关于configure: error: no acceptable C compiler found in $PATH

    Linux系统在安装python3的时候报错: $ ./configure --prefix=/usr/local/python3 checking build system type... x86_ ...

  4. rabbitmq学习(九) —— 关于消息队列的选型

    转自http://cmsblogs.com/?p=3846 在IM这种讲究高并发.高消息吞吐的互联网场景下,MQ消息中间件是个很重要的基础设施,它在IM系统的服务端架构中担当消息中转.消息削峰.消息交 ...

  5. Codeforces Round #370 (Div. 2) A. Memory and Crow 水题

    A. Memory and Crow 题目连接: http://codeforces.com/contest/712/problem/A Description There are n integer ...

  6. STM32 CRC-32 Calculator Unit

    AN4187 - Using the CRC peripheral in the STM32 family At start up, the algorithm sets CRC to the Ini ...

  7. ARM 编程平台+coresight

    http://www.keil.com/product/ DS-5:http://www.cnblogs.com/njseu/p/6023081.html http://www.arm.com/pro ...

  8. Linux Delay Accounting

    https://andrestc.com/post/linux-delay-accounting/ Ever wondered how long is your program spending wh ...

  9. Revit API改变风管及管件尺寸

    start , , )) < , , -)) < , dHeight = ;             ConnectorSetIterator csi = fi.MEPModel.Conn ...

  10. 蜻蜓FM涉嫌诈骗投资人和广告主源代码剖析

    引用自:https://github.com/cryfish2015/QingTingCheat 本文主要内容,引用自知乎的这篇文章:如何评价蜻蜓 FM 伪造用户活跃度等数据 感谢“左莫”.“任正”等 ...