Matrix 关于Anr 处理的总结

2023年 9月 25日 32.4k 0

anr 有好几个维度
1: cpu 性能被耗尽

2:死锁

3:慢方法

关于第一点在应用层是无能为力的,这个需要底层的支持,

对于死锁来说也可以从 crashHandler 处获取相应的信息,这个更方便 快捷 准确

Matrix 关于慢方法的统计

1:字节码插装
使用ASM 在编译器 想代码开始的时候插入一个代码开始的消息, 在代码运行结束的时候向方法插入一个执行结束的消息, 这是一种非常巧妙的方法,Matrix 针对性能上的考虑也做到了极致 ,在获取时间上面没有使用 System.currentTimeMillis() 这个方法,既然是计算时间差, 这个方法获取的时间是经过计算的,对于当前的使用场景并没有太大的意义,SystemClock.elapsedRealtime() 通过系统的启动时间即可

2: 使用Looper.logger Matrix 在处理这个logger的时候非常巧妙的先获取了一下 已经被 赋值到 looper 上的 logger, 让自己的logger 持有 这个logger ,那么就会保证在原有logger 不失效的同时,将自身的logger 插入进去, 同时还使用 idelHandler 的原理 来保证自身的logger 即使被替换了,那么也能重新将 logger 添加进去

3:手势 动画等事件的处理可能在上面两个维度都统计不到,就需要借助 Choreographer 或者 OnFrameMetricsAvailableListener 来处理了, 这里面的逻辑 可以去我的另一篇博客 Matrix 原理与技巧总结 fps 篇 看一下,由于时间的关系 代码就先不在这里分析了,

从常理上面来说Matrix 统计的都是慢方法,并没有统计anr 的产生,那么为什么这么做呢,这就和anr产生的原因有关
anr 有几种类型
1 dispatchtouch 类型
2 broadcase 类型
3 service 类型
4 contentprovider 类型

如果主线程卡死了,但是没有上面4种事件,就不会产生anr

就我了解的anr 监控方案还有2个,只不过Matirx 没有选择而已,没有选择的原因是不符合他们的业务逻辑,但并不是这个方法不能使用

1:类似WatchDog(系统重启服务)
性能损耗相对looper.logger来说比较小,自己定时开销肯定会小一些
在线程中执行一个while(true){
-->做一些标识的flag
--> 将这个 消息发送到handler 绑定的messagequeue 的front ,也就是主线程的front,
-->等待 30秒
-->如果 handler 中的消息被执行,那么标识符肯定会被改变
-->检查标识符
}

2:FileObserve
几乎没有性能上的开销
而且可以在其他进程中执行
而且在使用场景上非常适合拥有root 权限的智能设备上面(只有一个app产生track文件,不会收到其他app影响)

原理和使用
在anr 发生的时候,系统会向 data/anr/track_18_08(时间) 写一个文件,使用 FileObserve 监听这个目录,在写完的时候就可以操作这个文件
如果是在C端的情况下,会获取其他app 的anr,但是在智能设备端 ,运行的app不多,大都是自己开发的app,同时还能直接获取到anr 的信息,同时对性能几乎是没有损耗的
同时如果是android 5.0以上的系统,这个事件可能会被 selinux(Linux子安全系统) 拦截,由于root权限后是什么样子我还需要验证一下,

相关文章

服务器端口转发,带你了解服务器端口转发
服务器开放端口,服务器开放端口的步骤
产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
如何使用 WinGet 下载 Microsoft Store 应用
百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

发布评论