Android 开发高手课
张绍文
前微信高级工程师,Tinker 负责人
52721 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 62 讲
导读 (1讲)
模块一 高质量开发 (25讲)
Android 开发高手课
15
15
1.0x
00:00/00:00
登录|注册

10 | I/O优化(中):不同I/O方式的使用场景是什么?

作用
性能对比
CPU繁忙时的影响
实验结果
适用场景
缺点
优点
适用场景
写操作影响
读操作影响
同步写机制
延迟写机制
写操作特性
读操作特性
文件系统优化
文件读取时间
目录查找性能
NIO
多线程阻塞I/O
mmap
直接I/O
标准I/O
课后练习
总结
小文件系统
多线程阻塞I/O和NIO
I/O的三种方式
不同I/O方式的使用场景

该思维导图由 AI 生成,仅供参考

今天是 2019 年的第一天,在开始今天的学习前,先要祝你新年快乐、工作顺利。
I/O 是一个非常大的话题,很难一次性将每个细节都讲清楚。对于服务器开发者来说,可以根据需要选择合适的文件系统和磁盘类型,也可以根据需要调整内核参数。但对于移动开发者来说,我们看起来好像做不了什么 I/O 方面的优化?
事实上并不是这样的,启动优化中“数据重排”就是一个例子。如果我们非常清楚文件系统和磁盘的工作机制,就能少走一些弯路,减少应用程序 I/O 引发的问题。
在上一期中,我不止一次的提到 Page Cache 机制,它很大程度上提升了磁盘 I/O 的性能,但是也有可能导致写入数据的丢失。那究竟有哪些 I/O 方式可以选择,又应该如何应用在我们的实际工作中呢?今天我们一起来看看不同 I/O 方式的使用场景。

I/O 的三种方式

请你先在脑海里回想一下上一期提到的 Linux 通用 I/O 架构模型,里面会包括应用程序、文件系统、Page Cache 和磁盘几个部分。细心的同学可能还会发现,在图中的最左侧跟右上方还有 Direct I/O 和 mmap 的这两种 I/O 方式。
那张图似乎有那么一点复杂,下面我为你重新画了一张简图。从图中可以看到标准 I/O、mmap、直接 I/O 这三种 I/O 方式在流程上的差异,接下来我详细讲一下不同 I/O 方式的关键点以及在实际应用中需要注意的地方。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了不同I/O方式的特点和适用场景,包括标准I/O、直接I/O和mmap。标准I/O采用缓存I/O,能减少真正读写磁盘的次数,但可能导致数据丢失;直接I/O绕开页缓存机制,减少数据拷贝和系统调用的耗时,适用于缓冲I/O开销巨大的情况;mmap通过将文件映射到进程的地址空间,减少系统调用和数据拷贝,适合频繁读写同一块区域的情况。文章详细介绍了每种I/O方式的优缺点和适用场景,对于开发者来说,能够帮助他们选择合适的I/O方式来优化应用程序的性能。此外,还介绍了多线程阻塞I/O和NIO的使用场景,以及小文件系统的性能优化。总结来说,本文全面介绍了I/O的整个流程,不同的I/O方式的差异以及它们在实际工作中的适用场景,为读者提供了深入了解和应用I/O优化的知识。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Android 开发高手课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(12)

  • 最新
  • 精选
  • Swing
    很好奇,像微信这样一个权限普通的app,怎么接入的自己的小文件系统(或者说 替换原生的文件系统)?

    作者回复: 这个小文件系统是应用层的方案,只是把一大堆的小文件组织成一个超大文件。并没有替换原生的文件系统

    2019-02-13
    2
    6
  • 星风雪雨
    mmap,一次拷贝;我的理解是磁盘拷贝到主存,而普通文件是两次拷贝:磁盘-->页缓存-->用户空间,虽然是两次拷贝,但是页缓存-->用户空间是在内存拷贝,虽然多了一次,但是这次是内存操作,应该是很快的;那mmap速度相对读文件快,主要原因是系统调用少引起的吗?

    作者回复: 用户态的改变 + 频繁操作,也是非常耗时的

    2019-11-21
    3
  • 欢乐小熊
    Binder 通信的图有些不能理解 进程的用户空间与内核空间是通过 binder_mmap 类似匿名映射的方式分配的, 用户与内核之间是不需要拷贝的 数据的拷贝, 应该在内核空间不同进程的 Binder 缓冲区 不知理解的是否正确, 请老师指教

    作者回复: 用户到内核是要拷贝一次的

    2019-06-20
    3
    3
  • taotaomami
    “iowait高,io一定有问题” 这个观点有点异议,借用网上一篇文章对iowait的解释“%iowait 表示在一个采样周期内有百分之几的时间属于以下情况:CPU空闲、并且有仍未完成的I/O请求” iowait这个参数的值对我们观察io活动意义比较小

    作者回复: 这里其实想表达的是这段时间的io操作一定会比较高的意思,并不一定能说明代码有问题

    2019-01-06
    1
  • 神佑小鹿
    想请教下,mmap 映射的是用户缓冲区和 page cache 页缓存吗?copy/write 也只需要发生在 page cache 和磁盘?

    作者回复: 文件读写 mmap 映射的就是page cache,但是也不是绝对的

    2019-08-31
  • 老师好,文件IO这一块您讲的非常好,对我的帮助很大,谢谢了
    2019-01-01
    12
  • 李小四
    文中提到“我们使用 mmap 仅仅只需要一次数据拷贝”,这个说法是不准确的,内存映射的场景直接操作的就是映射到的内存,不需要额外的一次拷贝。 Binder的方案确实需要一次数据拷贝,那是Binder的机制决定的,而不是因为内存映射需要一次数据拷贝。 在Binder机制中,内存映射在一次通信过程中是单侧的:数据发送方通过transact将数据写入到内核态,这个过程需要一次数据拷贝(写入过程非内存映射,否则不需要“写”);而接收方直接映射到了这一块内存,接收的过程不需要内存拷贝,所以Binder机制需要一次数据拷贝。
    2021-03-08
    1
    3
  • 董尚斌
    真值,以前就只知道,写文件,读文件,具体实现的代码,怎么写。现在发现有些情况下的文件读写速度在不同设备上的表现方式的原因。 我做的最多的文件读操作是,全盘扫描本地文件(涉及读文件里面的字节来区分是否符合要求),以及多进程写日志的问题(aidl统一交给主应用的主进程,涉及文件锁和磁盘io频繁的问题) 听了最近的两节,感觉,这些地方可以适当的优化下。 谢谢,老师。
    2019-01-01
    3
  • elephant
    "微信也开发了一套叫 SFS 的小文件管理系统,主要用在朋友圈图片的管理...." 真的是跪着看微信的技术方案 orz
    2019-01-02
    1
    2
  • Mograine
    老师,我补习了一下iowait相关知识,因为我发现有些地方跟我的认知是冲突的,网上搜索后发现,很多博客纠正说,%iowait 高并不表示I/O有瓶颈问题。老师可以回答下我这个问题吗。比如https://www.cnblogs.com/probemark/p/5862293.html,老师你能解答下这个问题吗
    2020-03-05
    1
收起评论
显示
设置
留言
12
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部