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

11 | I/O优化(下):如何监控线上I/O操作?

GOT Hook
PLT Hook
动态代理
插桩
解决非主线程I/O问题
I/O Canary接入
存储结构和算法的优化
Buffer复用
不压缩安装包
mmap或者NIO方式
资源泄漏
重复读
读写Buffer过小
主线程I/O
操作耗时
读取文件信息
Native Hook
Java Hook
课后练习
线上需求
监控方案选择
优化方式
检查每一处I/O调用
抽象出规则
监控内容
方法
在线上持续监控应用程序中I/O的使用
发现不合理的I/O操作
I/O性能的方法
总结
I/O与启动优化
线上监控
I/O跟踪
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 的整个调用流程如下。
java : FileInputStream -> IoBridge.open -> Libcore.os.open
-> BlockGuardOs.open -> Posix.open
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
立即购买
登录 后留言

全部留言(9)

  • 最新
  • 精选
  • gmm
    想问下 libjavacore.so、libopenjdkjvm.so、libopenjdkjvm.so 是系统的共享库,为什么 hook 修改了这些库,不会影响到其他的 APP 呢

    作者回复: 如果没有root,只能影响自己的进程空间

    2019-11-26
    5
  • 欢乐小熊
    看了 Matrix IO 监控的源码, 被其骚操作震惊了, 通过 .so 库名找到了 mmap 区的库地址, 然后 hook 函数的实现, 有趣极了

    作者回复: 这个是常用操作喔

    2019-06-21
    2
    4
  • iniesta2014
    对大文件使用 mmap 或者 NIO 方式? 这样的话,大文件 mmap不是需要很大虚拟内存吗?

    作者回复: 相比于物理内存,虚拟内存还是比较大的。而且如果支持64位的话,虚拟内存的空间就不再是问题了

    2019-04-18
    3
  • 神佑小鹿
    2013 年我在做 Multidex 优化的时候,发现代码中... 老师,可以讲一下这个是如何优化的吗?

    作者回复: 主要就是 1. 从zip快速提取dex 2. dex解压的多进程同步 3. 存储空间不足时的提示 4. 安全性检测 ....

    2019-08-31
    2
  • 小洁
    请问下,上面说到"采用 Native Hook 的监控方法性能损耗基本可以忽略",请问下在监控前和加入Native Hook 之后是通过什么方式去对比性能损耗的而且保证这个统计的准确性,这个统计本身也会是一个损耗吗

    作者回复: 之前是大家循环执行一万次,看耗时的差异

    2019-03-15
    1
  • 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-06
    1
  • 绍文大佬,文章中这句话没理解:“对启动过程需要的文件,我们可以指定在安装包中不压缩”。默认打的apk包中resource、resource.arsc文件不是就是没压缩过的吗?如何指定不压缩类

    作者回复: 默认是没有压缩的,但是事实上大多数的应用为了安装包体积,都把它们压缩了

    2019-02-19
    1
  • 木木哈
    给大佬献上膝盖
    2019-03-28
    4
  • 聪明的傻孩子
    过去五年,再看依然能学到东西
    2024-02-21归属地:重庆
    1
收起评论
显示
设置
留言
9
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部