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 框架后已经简化了我 ...
随机推荐
- Python之路--Python初识
Python简介 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆(中文名字:龟叔)为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程 ...
- centos7.3网络配置
一.关闭NetworkManager 默认状态下最小化安装使用NetworkManager这个服务来控制联网的,但是这个配置在配置生产环境服务器时一般不会使用,而是使用系统自带的network服务,更 ...
- Apache虚拟主机测试
一.虚拟机主机简介 部署多个站点,每个站点,希望用不同的域名和站点目录,或者是不同的端口,或不同的ip,就需要虚拟主机功能.简单的说一个http服务要配置多个站点,就需要虚拟主机.(一句话一个http ...
- Android拨打电话不弹出系统拨号界面总结
我在网上搜了一下,解决这个问题,有两种方式: 1.反射调用系统底层方法,并获取系统权限 反射调用的代码如下: Class phoneFactoryClass = Class.forName(" ...
- 4444: [Scoi2015]国旗计划
4444: [Scoi2015]国旗计划 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 485 Solved: 232 Description A国 ...
- Ping过程&ICMP
1.ICMP(Internet控制消息协议) ICMP=Internet Control Message Protocol 它是TCP/IP协议族的一个子协议 作用:用于在IP主机.路由之间传递控制消 ...
- 设计模式之第13章-职责链模式(Java实现)
设计模式之第13章-职责链模式(Java实现) “请假都那么麻烦,至于么.”“咋的了?”“这不快过年了么,所以我想早两天回去,准备一下,买买东西什么的,然后去给项目经理请假,但是他说快过年了,所以这个 ...
- 设计模式之第9章-原型模式(Java实现)
设计模式之第9章-原型模式(Java实现) “快到春节了,终于快放假了,天天上班好累的说.”“确实啊,最近加班比较严重,项目快到交付了啊.”“话说一到过节,就收到铺天盖地的短信轰炸,你说发短信就发吧, ...
- Python-S9-Day115——Flask Web框架基础
01 今日内容概要 02 内容回顾 03 Flask框架:配置文件导入原理 04 Flask框架:配置文件使用 05 Flask框架:路由系统 06 Flask框架:请求和响应相关 07 示例:学生管 ...
- [oldboy-django][6其他]rest framwork有关事
官网地址: https://github.com/encode/django-rest-framework 英文教程:http://www.django-rest-framework.org/tuto ...