概述
I/O监控,可以监控APP运行时,出现的I/O问题,包括文件主线程I/O,读写buffer太小,重复读,文件句柄未关闭。
检测原理
文件I/O监控采用的native hook的方式,通过hook文件操作接口,来收集I/O信息。
文件句柄关闭监控采用的是Android 框架提供的StrictMode。StrictMode有专门针对文件close监控的dalvik.system.CloseGuard模块。只需通过反射机制,打开CloseGuard监控,并动态代理CloseGuard中的Reporter接口,即可监控到文件/句柄未关闭导致的泄露。
以FileInputStream为例,当gc的时候会调用FileInputStream中的finalize方法,其中guard用于标记gc前FileInputStream是否已经调用close关闭句柄。如果gc之前还没有close,调用guard.warnIfOpen。我们通过反射代理guard.warnIfOpen中的REPORTER.report方法获取泄露信息。
检测场景
1.主线程IO
耗时的IO操作不能占据主线程太久,当监控到满足以下两个条件,SDK将上报:
1)操作线程为主线程
2)连续读写超过一定阈值(500ms)或单次write/read耗时超过一定阈值 (13ms)
2.读写buffer太小
Buffer过小,会导致read/write的次数增多,从而影响性能。监控条件为:
1)Buffer小于一定阈值 (4KB)
2)Read/write的次数超过一定阈值 (20)
3)最大连续读/写时间大于 13ms
3.重复读
如果频繁地读某个文件,说明这个文件的内容很常被用到,可以通过缓存来提高效率。监控条件为:
1)文件最大连续读写时间大于13ms(如果文件最大连续读写时间<13ms,就不会加入观察)
2)同一个文件,连续两次读操作间隔小于17ms
3)同一线程读取某个文件的次数超过一定阈值(5次)(这里要求读取的文件路径,堆栈,线程,文件大小等信息均一样)
4.文件句柄关闭泄漏监控:
文件句柄关闭泄漏指的是打开资源包括文件/cursor等,没有及时close,引起泄露。SDK检测到文件open之后没有对应的close,将会上报泄漏。
SQLite概述:在移动端开发中,大量业务使用SQLite操作数据库。
数据库的建表、增删改查涉及频繁的IO,耗时一般比较大;而且sql语句的写法,对操作耗时影响也很大。
所以,数据库的操作,要求:
1)尽量不要在主线程操作;
2)sql语句按照高性能方式编写,避免低效检索。
目前,OAPM的SQLite检测主要检测和监控出第1)种场景,帮助业务发现主线程中的数据库操作。
检测原理
如果将SQLiteDebug.DEBUG_SQL_TIME设置为true,在SQLite的每一个语句执行之后,均会回调native层的sqlite3_profile()方法。sqlite3_profile()能获取到sql语句信息以及sql语句的耗时情况。
所以,我们可以通过native hook的方式,hook sqlite3_profile()方法,即可获取到数据库操作相关的所有语句。基于数据库的语句以及调用语句的场景,我们能知道:
1)当时调用语句所在的进程、线程信息
2)当时调用语句的堆栈
3)语句执行耗时
4)具体语句是什么(然后可以基于sql语句建立语法树,判断sql语句是否高效)
检测场景
目前检测的场景是,在主线程操作sql语句时,会上报检测问题。
所以,如果在应用的主线程中,执行了SQLite的操作语句,均会上报问题

2386

被折叠的 条评论
为什么被折叠?



