系统源码分析利用优化性能优化

ANR监控方案总结

2022-09-10  本文已影响0人  ModestStorm

1.前言

ANR比较棘手在于,没有崩溃日志,定位问题比较困难,而且ANR是必须要解决的问题。

Android对ANR的监控机制
Android应用程序是通过消息来驱动的,Android某种意义上也可以说成是一个以消息驱动的系统,UI、事件、生命周期都和消息处理机制息息相关。Android的ANR监测方案也是一样,大部分就是利用了Android的消息机制。


anr.png

2.主流的ANR监控方案

主流的ANR监控方案:FileObserver,WatchDog,Looper.loop。它们都各有优缺点,无法覆盖所有情况,所以在线上使用的时候可以结合这几种方案一起使用。

2.1 FileObserver实现ANR监控

当ANR发生的时候,我们是可以通过监听该文件目录data/anr/的写入情况来判断是否发生了ANR,看起来这是一个不错的时机。需要注意的是,所有应用发生ANR的时候都会进行回调,因此需要做一些过滤与判断,如包名、进程号等。

优点:

  1. 基于原生接口调用,时机和内容准确
  2. 无性能问题实现简单

缺点:
最大的困难是兼容性问题,这个方案受限于Android系统的SELinux机制,5.0以后基本已经使低权限应用无法监听到trace文件了,但是可以在开发内测阶段通过root手机进行监控。

2.2 ANR-WatchDog实现ANR监控

ANR-WatchDog是参考Android WatchDog机制(com.android.server.WatchDog.java)起个单独线程向主线程发送一个变量+1操作的消息,然后自我休眠sleep 自定义ANR的阈值一般是5s,休眠过后判断变量是否+1完成,如果未完成则告警。

watchdog.png

优点:

  1. 兼容性好,各个机型版本通用
  2. 无需修改APP逻辑代码,非侵入式
  3. 逻辑简单,性能影响不大

缺点:
无法保证能捕捉所有ANR,对阈值的设置直接影响捕获概率.比如如果设置了5s就无法捕获10s的Receiver和20s的service 引起的ANR。

2.3 Looper.loop实现ANR监控

巧妙的利用了Android原生Looper.loop中的一个log打印逻辑。
这个log打印逻辑正是在Message消息分发前后,大部分的性能卡顿问题都是在这里发生的,监控这两个逻辑之间的时间差就可以得到当前主线程的卡顿状态,如果超时则获取trace信息并上报。

实现原理:开启子线程执行,会消耗cpu资源,谨慎开启,开发中一般针对部分用户下发开关:

  1. 设置Looper.setPrinter(自定义printer)实现println方法;
  2. 在消息执行前后,Looper会调用
    Looper.mPriter.pritlin(“>>>>> dispatch msg.target msg.callBack,msg.what”)//子线程开启收集线程堆栈信息
    Looper.mPriter.pritlin(“<<<<<< finish msg.target msg.callBack,msg.what”)//子线程结束收集线程堆栈信息
  3. 首先需要判断msg.target的Looper是否等于主线程的Looper.
  4. 其次计算这两个函数前后时间差是否超过200ms超过的话就上报堆栈调用信息。

优点:

  1. 灵活配置可监控常见APP应用性能也可作为一部分场景的ANR监测,并且可以准确定位ANR和耗时调用栈。

  2. 谷歌已经明确标注This must be in a local variable, in case a UI event sets the logger这个looger对象是可以被更改的,已经有开发者遇到在使用WebView时logger被set为Null导致,进而造成监控失败。

3.如果dispatchMessage消息执行的非常久是无法触发监控的逻辑。

4.无法监控CPU资源紧张造成系统卡顿,无法响应的ANR

2.4 注册信号函数

使用注册信号函数机制监听SINGAL_QUIT信号,可以监听ANR和Crash触发逻辑。可以作为FileObserver在5.0以后因权限问题无法监测data/anr目录的使用。
因为当应用发生crash和ANR的时候,系统会向目标进程发送SIGNAL_QUIT信号,应用虚拟机捕获到信号以后会收集系统信息输出到日志文件中(data/anr/trace.txt)然后kill掉目标进程。trace文件中数据过大,可以根据当前时间节点和进程id进行信息过滤。详情参考:让Native Crash 与ANR无处发泄

3.总结

ANR监控方案各有优劣,开发中一般组合多个共同使用。
Crash,ANR,卡顿最难的是异常信息的收集上传,收集到信息后可以根据日志进行分析进而解决问题。信息(一般是将日志保存在本地,有效期限是七天)上传一般都是通过开关动态下发的,目的是为了节省带宽和服务端的存储压力。千万级的用户数据量会很大。

在灰度期间重点观察指标是否正常,如果正常扩大灰度继续观察,不正常的话就停止灰度。然后定位问题是升级还是采用热修复。

上一篇 下一篇

猜你喜欢

热点阅读