Java IO 学习(三)缓冲IO / 直接IO / 内存映射
缓冲IO
在介绍缓冲IO之前需要先了解一下常用的机械硬盘的原理与特点
一个机械硬盘中装有多个盘片
每个盘片上有多个同心圆(磁道)
每个同心圆又由多个弧(扇区)组成,每个弧上都记录了等量的数据(比方说512byte)
如果发起一个随机读写请求,磁头需要先找到对应的磁道,然后等待对应的扇区旋转到磁头正下方才能开始读取数据(民用机械硬盘的转速一般在5400或者7200RPM,工业界倒是经常使用10000RPM的机械硬盘。但是它们的寻道时间大概都在几ms到十几ms左右)
机械硬盘的顺序读写很快(一般在100-200MB/s),但是随机读写很慢(寻道时间在十几ms,导致随机读写的iops只有几十)
假定我们不做任何额外的优化处理,在用户发起读数据请求的时候,直接调用硬盘驱动读取磁盘数据并返回
设想一个场景:循环调用read方法读取文件,但是每次只读取较少的数据(比方说每次只读一个byte)。那么每次read请求都对应于一次对磁盘的随机读写(两次读请求之前需要重新寻道),也就是说read操作的tps只有几十。
也就是说此时磁盘占用率为100%,但是只能提供不到100byte/s的数据读取率,这显然是不可接受的。
Linux对此有个很简单的优化,就是在内核中维护一块缓冲区(buffer cache),在用户第一次调用read读取数据的时候,无论用户想要读取的数据有多小,都会一次性从磁盘中加载一段数据放到缓冲区中,这样用户下一次调用read方法的时候可以直接从缓冲区中返回数据,不用再次访问磁盘了。
write方法也是同理,用户写入的数据不是直接落盘,而是先写到kernel中的缓冲区里,按照一定的策略批量刷盘。当然也可以调用flush方法强制将缓存区的数据落盘。
这个优化极大的提高了顺序读写的效率。由于直接读写的是kernel中的缓冲区而不是磁盘,这种IO被称为缓冲IO。
直接IO
一般来说,上面介绍的缓冲IO已经足够应付日常需求了。但是像数据库这种极度依赖IO的应用程序,为了追求极致的性能,往往更加愿意自己直接操作磁盘。
直接IO可以直接将数据从磁盘复制到用户空间,或者将数据从用户空间写到磁盘,减少了kernel中的缓冲区这一环节,这是直接IO可以提高性能的原理。
但是如果用得不好就悲剧了,所以直接IO只在少数场景下使用。
内存映射
先给出mmap的官方文档
mmap方法会返回一个void *类型的指针ptr,它指向进程逻辑空间中的一个地址。
后续如果想要读写文件,无需调用read/write方法, 而是直接操作这个ptr指针即可。
用户试图向ptr指针指向的空间读写数据时,由于MMU无法在物理内存中找到对应的地址,会触发一次缺页中断,OS会去硬盘中找到对应的数据并复制到内存中,然后用户就能正常完成读写操作了。这个过程是由操作系统自动完成的。
为什么说内存映射效率比缓冲IO要高?
我们回忆一下缓冲IO的工作流程:
1. 用户调用read方法
2. 调用系统调用,触发中断,进程从用户态进入内核态
3. 从硬盘中读取数据并复制到kernel缓冲区
4. 将数据从kernel缓存区复制到用户提供的byte数组中
5. 进程从内核态返回到用户态
完成
从上面的流程中我们可以看到,调用一次read方法,最多可能会引起两次用户态与内核态之间的切换,以及两次数据复制
而内存映射呢?
1. 用户试图访问ptr指向的数据
2. MMU解析失败,触发缺页中断,程序从用户态进入到内核态
3. 从硬盘中读取数据并复制到进程空间中ptr指向的逻辑空间里
4. 进程从内核态返回到用户态
完成
可以看出,试图访问内存映射文件,最多可能会引起两次用户态与内核态之间的切换,以及一次数据复制
也就是说,内存映射与缓冲IO相比,可以节省数据复制带来的开销,因此效率较高。
参考资料
Java IO 学习(三)缓冲IO / 直接IO / 内存映射的更多相关文章
- Java开发学习(三十七)----SpringBoot多环境配置及配置文件分类
一.多环境配置 在工作中,对于开发环境.测试环境.生产环境的配置肯定都不相同,比如我们开发阶段会在自己的电脑上安装 mysql ,连接自己电脑上的 mysql 即可,但是项目开发完毕后要上线就需要该配 ...
- Java开发学习(三十六)----SpringBoot三种配置文件解析
一. 配置文件格式 我们现在启动服务器默认的端口号是 8080,访问路径可以书写为 http://localhost:8080/books/1 在线上环境我们还是希望将端口号改为 80,这样在访问的时 ...
- Java NIO学习笔记九 NIO与IO对比
Java NIO与IO Java nio 和io 到底有什么区别,以及什么时候使用nio和io,本文做一个比较. Java NIO和IO之间的主要区别 下表总结了Java NIO和IO之间的主要区别, ...
- Java虚拟机学习(1):体系结构 内存模型
一:Java技术体系模块图 Java技术体系模块图 二:JVM内存区域模型 1.方法区 也称"永久代" ."非堆", 它用于存储虚拟机加载的类信息.常量.静态 ...
- Java开发学习(二十四)----SpringMVC设置请求映射路径
一.环境准备 创建一个Web的Maven项目 参考Java开发学习(二十三)----SpringMVC入门案例.工作流程解析及设置bean加载控制中环境准备 pom.xml添加Spring依赖 < ...
- Java IO学习--(三)通道
Java IO中的管道为运行在同一个JVM中的两个线程提供了通信的能力.所以管道也可以作为数据源以及目标媒介. 你不能利用管道与不同的JVM中的线程通信(不同的进程).在概念上,Java的管道不同于U ...
- java 多线程学习笔记(二) -- IO密集型任务
IO密集型是指对IO操作较多的任务.下面以查询一些股票价格任务为例: YahooFinance.java public class YahooFinance { public static doubl ...
- Linux非阻塞IO(三)非阻塞IO中缓冲区Buffer的实现
本文我们来实现回射服务器的Buffer. Buffer的实现 上节提到了非阻塞IO必须具备Buffer.再次将Buffer的设计描述一下: 这里必须补充一点,writeIndex指向空闲空间的 ...
- linux io 学习笔记(03)---共享内存,信号灯,消息队列
system V IPC 1)消息队列 2)共享内存 3)信号灯(信号量集) 1.消息队列. ipcs -q 查看系统中使用消息队列的情况 ipcrm -q +msqid 删除消息队列 消息队列工作原 ...
- Java开发学习(三十五)----SpringBoot快速入门及起步依赖解析
一.SpringBoot简介 SpringBoot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化 Spring 应用的初始搭建以及开发过程. 使用了 Spring 框架后已经简化了我 ...
随机推荐
- nowcoder N约数个数
n的约数个数 题目:t次询问,每次给你一个数n,求在[1,n]内约数个数最多的数的约数个数 数据:对于100%的数据,t <= 500 , 1 <= n <= 10000000000 ...
- DFS:BZOJ1085-骑士精神
题目: 1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1461 Solved: 796 [Submit][ ...
- js:随记
typeof:没有大写,因为typeof是运算符 *1:是转数字 +string:是转数字,在Date对象上是getTime ""+:是转字符串 "":bool ...
- 朴素贝叶斯python小样本实例
朴素贝叶斯优点:在数据较少的情况下仍然有效,可以处理多类别问题缺点:对于输入数据的准备方式较为敏感适用数据类型:标称型数据朴素贝叶斯决策理论的核心思想:选择具有最高概率的决策朴素贝叶斯的一般过程(1) ...
- loj6392 「THUPC2018」密码学第三次小作业 / Rsa
还是挺好做的,\((e_1,e_2)=1 \Rightarrow e_1s+e_2t=0\),\(m \equiv m^1 \equiv m^{e_1s+e_2t} \equiv c_1^s c_2^ ...
- laravel5.2总结--ORM模型
ORM模型简介 1>什么是ORM? ORM,即 Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在操作具体的 ...
- Quorum机制与NRW算法总结
Quorum机制与NRW算法总结 1.Quorum机制 Quorum,原指为了处理事务.拥有做出决定的权力而必须出席的众议员或参议员的数量(一般指半数以上). 2.NRW算法 NRW算法是基于Quor ...
- 【Word Break】cpp
题目: Given a string s and a dictionary of words dict, determine if s can be segmented into a space-se ...
- macOS Sierra 触控板无法三指拖移窗口、三指选中文字的解决方法
问题:升级macOS Sierra新系统后,发现触摸板无法进行三指拖移窗口.三指选定文字的操作.在“系统偏好设置”——“触控板”内无法进行设置. 解决:“系统偏好设置”——“辅助功能”——“鼠标与触控 ...
- iOS自定义控件创建原理(持续更新)
前言 因为如果要创建各种自定义控件根据需求的不同会有很多的差别,所以我就在这里,分析一些自定义控件的创建实现方法 弹出视图 1.把要弹出的视图装在一个控制器里面,自定义转场动画 2.创建一个弹出视图, ...