11 | I/O优化(下):如何监控线上I/O操作?
张绍文
该思维导图由 AI 生成,仅供参考
通过前面的学习,相信你对 I/O 相关的基础知识有了一些认识,也了解了测量 I/O 性能的方法。
但是在实际应用中,你知道有哪些 I/O 操作是不合理的吗?我们应该如何发现代码中不合理的 I/O 操作呢?或者更进一步,我们能否在线上持续监控应用程序中 I/O 的使用呢?今天我们就一起来看看这些问题如何解决。
I/O 跟踪
在监控 I/O 操作之前,你需要先知道应用程序中究竟有哪些 I/O 操作。
我在专栏前面讲卡顿优化的中提到过,Facebook 的 Profilo 为了拿到 ftrace 的信息,使用了 PLT Hook 技术监听了“atrace_marker_fd”文件的写入。那么还有哪些方法可以实现 I/O 跟踪,而我们又应该跟踪哪些信息呢?
1. Java Hook
出于兼容性的考虑,你可能第一时间想到的方法就是插桩。但是插桩无法监控到所有的 I/O 操作,因为有大量的系统代码也同样存在 I/O 操作。
出于稳定性的考虑,我们退而求其次还可以尝试使用 Java Hook 方案。以 Android 6.0 的源码为例,FileInputStream 的整个调用流程如下。
在Libcore.java中可以找到一个挺不错的 Hook 点,那就是BlockGuardOs这一个静态变量。如何可以快速找到合适的 Hook 点呢?一方面需要靠经验,但是耐心查看和分析源码是必不可少的工作。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文深入探讨了监控线上I/O操作的方法,重点介绍了两种I/O跟踪方法:Java Hook和Native Hook。对于Native Hook方法,文章详细介绍了PLT Hook和GOT Hook的实现方式,并推荐了Profilo中的做法。此外,文章还讨论了监控内容,包括主线程I/O、读写Buffer、重复读和资源泄漏等方面的监控要点。通过对Native Hook的耗时数据分析,文章指出了该监控方法的性能损耗基本可以忽略,适用于线上使用。此外,文章还提到了I/O与启动优化的相关内容,包括对必不可少的I/O操作进行优化、使用mmap或者NIO方式对大文件进行处理、不压缩安装包中的文件以加快启动速度等。总的来说,本文为读者提供了监控线上I/O操作的实用方法和技术特点,对于需要进行I/O优化的开发人员具有一定的参考价值。文章还提到了在实验室到线上的迭代过程中需要进行大量的灰度测试和反复的优化,以及课后练习的内容,鼓励读者参与到开源事业中。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Android 开发高手课》,新⼈⾸单¥59
《Android 开发高手课》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(9)
- 最新
- 精选
- gmm想问下 libjavacore.so、libopenjdkjvm.so、libopenjdkjvm.so 是系统的共享库,为什么 hook 修改了这些库,不会影响到其他的 APP 呢
作者回复: 如果没有root,只能影响自己的进程空间
2019-11-265 - 欢乐小熊看了 Matrix IO 监控的源码, 被其骚操作震惊了, 通过 .so 库名找到了 mmap 区的库地址, 然后 hook 函数的实现, 有趣极了
作者回复: 这个是常用操作喔
2019-06-2124 - iniesta2014对大文件使用 mmap 或者 NIO 方式? 这样的话,大文件 mmap不是需要很大虚拟内存吗?
作者回复: 相比于物理内存,虚拟内存还是比较大的。而且如果支持64位的话,虚拟内存的空间就不再是问题了
2019-04-183 - 神佑小鹿2013 年我在做 Multidex 优化的时候,发现代码中... 老师,可以讲一下这个是如何优化的吗?
作者回复: 主要就是 1. 从zip快速提取dex 2. dex解压的多进程同步 3. 存储空间不足时的提示 4. 安全性检测 ....
2019-08-312 - 小洁请问下,上面说到"采用 Native Hook 的监控方法性能损耗基本可以忽略",请问下在监控前和加入Native Hook 之后是通过什么方式去对比性能损耗的而且保证这个统计的准确性,这个统计本身也会是一个损耗吗
作者回复: 之前是大家循环执行一万次,看耗时的差异
2019-03-151 - HI你好,Canary_Io源码中,检测 重复读,有这样代码 bool RepeatReadInfo::operator==(const RepeatReadInfo &target) const { return target.path_ == path_ && target.java_thread_id_ == java_thread_id_ && target.java_stack_ == java_stack_ && target.file_size_ == file_size_ && target.op_size_ == op_size_; } 为什么这里要检测 op_size,这个貌似代表的是当前总的buff的大小,这个值就可以代表内容是一样的吗
作者回复: 这里不检查也是可以的,有堆栈跟size应该就ok
2019-03-061 - 林绍文大佬,文章中这句话没理解:“对启动过程需要的文件,我们可以指定在安装包中不压缩”。默认打的apk包中resource、resource.arsc文件不是就是没压缩过的吗?如何指定不压缩类
作者回复: 默认是没有压缩的,但是事实上大多数的应用为了安装包体积,都把它们压缩了
2019-02-191 - 木木哈给大佬献上膝盖2019-03-284
- 聪明的傻孩子过去五年,再看依然能学到东西2024-02-21归属地:重庆1
收起评论