ANR详解

本文围绕Android的ANR(Application Not Responding)展开,介绍了其概念、分类、触发原因和原理。详细阐述了ANR分析方法,包括日志获取与分析,还列举了iowait高、主线程执行耗时操作等经典案例,为解决Android应用无响应问题提供参考。

一: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 ,看内存结构

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值