ANR问题分析定位

    ANR(Application Not Responding)通常发生在主线程被长时间阻塞,导致无法响应用户的操作,一般会弹应用无响应的对话框让用户选择等待或者强制退出。

一、ANR产生的条件

(1)主线程:只有应用程序的主线程响应超时才会产生ANR

(2)超时时间:产生 ANR 的上下文不同,超时时间也会不同,但只要在这个时间上限内没有响应就会ANR

(3)输入事件/特定操作:输入事件是指按键、触屏等设备输入事件,特定操作是指 BroadcastReceiver 和 Service 的生命周期中的各个函数,产生 ANR 的上下文不同,导致 ANR 的原因也会不同

需要注意的是:主线程做耗时操作本身是不会产生ANR的,如果不需要应用响应操作是不会产生ANR的。

二、ANR类型

(1)KeyDispatch Timeout :按键或触摸事件在特定时间内无响应,超时时间5秒。

(2)Broadcast Timeout :BroadcastReceiver在特定时间内无法处理完成,前台广播10秒,后台广播60秒。

(3)Service Timeout :Service在特定的时间内生命周期函数无法处理完成,前台服务20秒,后台服务200秒。

(4)ContentProvider Timeout :ContentProvider在特定的时间内没有完成发布,超时时间10秒。

三、ANR原因

(1)应用在主线程上执行耗时 的 I/O操作;

(2)应用在主线程上进行长时间的计算;

(3)主线程在对另一个进程进行同步 binder 调用,而后者需要很长时间才能返回。

(4)主线程处于阻塞状态,等待另一个线程的锁。

(5)主线程在进程中或通过 binder 调用与另一个线程之间发生死锁。主线程不只是在等待长操作执行完毕,而且处于死锁状态。

四、ANR分析基本流程

1、日志抓取

通常我们都知道通过adb pull /data/anr/traces.txt xxx获取trace.txt文件来分析卡顿的地方:

adb pull /data/anr/traces.txt 本地目录

但有的手机没权限抓取,则使用adb bugreport获取错误日志:

adb bugreport 本地目录

一份完整的bugreport包含下面的信息,对分析ANR问题很关键

Log名称

作用

获取命令

system.log

包含ANR发生时间点信息、ANR发生前的CPU信息,还包含大量系统服务输出的信息

adb logcat –b system

main.log

包含ANR发生前应用自身输出的信息,可供分析应用是否有异常;此外还包含输出的GC信息,可供分析内存回收的速度,判断系统是否处于低内存或内存碎片化状态

adb logcat –b main

event.log

包含AMS与WMS输出的应用程序声明周期信息,可供分析窗口创建速度以及焦点转换情况

adb logcat –b event

kernel.log

包含kernel打出的信息,LowMemoryKiller杀进程、内存碎片化或内存不足,mmc驱动异常都可以在这里找到。

2、分析日志

备注:此处缺一个图,因可能涉及项目隐私,后续会通过demo来补充。

在main log(见上图红色箭头)搜索“ANR in”,查看发生的时间和进程,在 mainlog 日志分析发生 ANR 时的 CPU 状态

在 traces.txt 找到 ANR 信息(发生 ANR 时间节点、主线程状态、事故点、ANR 类型),根据进程寻找主线程的trace,发现被blocked的堆栈等信息,

在 traces.txt 分析发生 ANR 时的 GC 情况(分析内存)

3、结合源码分析

有可能通过这两个步骤无法定位到ANR发生的原因,那就需要更深入的分析问题了。

备注:此处后续也会通过demo来补充。

猜你喜欢

转载自blog.csdn.net/qq_21154101/article/details/127435010