一:ANR的概念
ANR(Application Not Responding)的监测原理本质上是消息机制,设定一个delay消息,超时未被移除则触发ANR。具体逻辑处理都在system server端,包括发送超时消息,移除超时消息,处理超时消息以及ANR弹框展示等;对于app而言,触发ANR的条件是主线程阻塞。
二:ANR的分类
Input ANR:按键或触摸事件在5s内无响应
Service ANR:前台20s,后台200s ; (startForeground超时10s)
Broadcast ANR:前台10s,后台60s
ContentProvider ANR:10s
三:触发ANR的常见原因

四:ANR原理
4.1 Input ANR

PS:InputDispatcher 启动后,会启动InputThread ,在死循环内不断监听、下发input事件
4.2 Service ANR
埋雷

拆雷

爆雷

4.3 Broadcast ANR
PS:只有发送有序广播,才有可能发生anr
埋雷

拆雷

爆雷

4.4 ContentProvider ANR
正常的provider是没有anr监控的,只有用ContentProviderClient进行增删改查才会有anr监控。
埋雷

拆雷

爆雷

五:ANR分析
5.1 日志获取
mtk:mtklog、data/anr、data/aee_exp。
data/anr和data/aee_exp可以通过Tinno_tool.apk导出。Aee是mtk的监测机制,当发生anr、crash之类的异常时,会自动生成db文件,db文件里包含很多问题现场的dump信息。
Qcom:bugreport。
adb shell bugreportz -p。等bugreport生成后,用adb pull出来即可。Bugreport会把data/anr目录下的trace文件拷贝出来。
5.2 日志分析
5.2.1 mobile log分析
Event log里搜am_anr,可以看到anr发生的时间、进程号、进程名称、anr原因等

Sys_log 里搜ANR in ,可以看到anr发生时的dump信息。

(1) ANR in com.android.systemui ANR进程名
(2) Reason: Input dispatching timed out ANR原因
(3) Load: 16.86 / 17.44 / 16.16 前1,前5,前15分钟的CPU负载,通常看变化趋势。
这个和CPU的核数有关,8核的CPU load是16.86,平均到单核的CPU load是2.1
(4) Output from /proc/pressure/memory 前10,前60,前300秒的memory负载。

(5) CPU usage from 1ms to 13317ms later (2023-05-04 13:39:21.000 to 2023-05-04 13:39:34.316) 统计的时间区域
(6) 23% TOTAL: 13% user + 9.3% kernel + 0.1% iowait + 0.1% softirq 整机负载情况
5.2.2 trace分析
根据am_anr打印出来的anr发生时间点,在data/anr里找到对应时间点的trace,通过trace文件中的Cmd line确认trace文件是对应的。

时间戳、pid、进程名都对得上。找到main

nice 代表该线程优先级,nice的取值范围为-20到19。通常来说nice的值越大,进程的优先级就越低,获得CPU调用的机会越少,nice值越小,进程的优先级则越高,获得CPU调用的机会越多。
utm:该线程在用户态所执行的时间(单位是jiffies)
stm:该线程在内核态所执行的时间
线程的cpu耗时是两者相加(utm+stm),utm,stm 单位换算成时间单位为 1 比 10ms。
core:后面的数字表示的跑在哪个核上,core=5表示打印这段日志时该线程跑在大核CPU5上。
六:经典案例
6.1 iowait高

6.2 主线程无卡顿,处于正常状态堆栈

主线程堆栈就是一个很正常的空闲堆栈,表明主线程正在等待新的消息。
如果ANR日志里主线程是这样一个状态,那可能有两个原因:
该ANR是CPU抢占或内存紧张等其他因素引起
这份ANR日志抓取的时候,主线程已经恢复正常
遇到这种空闲堆栈,可以先分析CPU、内存的情况。其次可以关注抓取日志的时间和ANR发生的时间是否相隔过久,时间过久这个堆栈就没有分析意义了。
6.3 主线程执行耗时操作

6.4 主线程被锁阻塞

6.5 CPU被抢占

6.6 内存紧张导致ANR

(1) Kswapd0是否占据前三
(2) main log中搜索lowmemorykiller: Kill 看kill进程的adj
(3) 如果比较容易复现,可以在anr发生前后dumpsys meminfo ,看内存结构
本文围绕Android的ANR(Application Not Responding)展开,介绍了其概念、分类、触发原因和原理。详细阐述了ANR分析方法,包括日志获取与分析,还列举了iowait高、主线程执行耗时操作等经典案例,为解决Android应用无响应问题提供参考。
3444

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



