Android ANR问题总结

一、概述

ANR(Application Not Responding), 如果 Android 应用的界面线程处于阻塞状态的时间过长,会触发“应用无响应”(ANR) 错误。如果应用位于前台,系统会向用户显示一个对话框,如图 1 所示。ANR 对话框会为用户提供强行退出应用的选项。

图 1. 向用户显示的 ANR 对话框

二、ANR分类

Input dispatching timed out:输入时间分发超过5s,包括按键和触屏事件。

Broadcast of Intent:前台广播需要在10s内完成,后台广播需要在60s内完成。

executing service:前台服务需要在20s内完成,后台则需要在200s内完成。

ContentProvider:几乎非常少见,publish执行未在10s内完成。

Context.startForegroundService() did not then call Service.startForeground():应用调用startForegroundService,然后5s内未调用startForeground出现ANR或者Crash,此问题属于应用未适配Android版本sdk。

三、产生ANR的原因分析

1. 诊断 ANR 时需要考虑以下几种常见模式:

1、应用在主线程上非常缓慢地执行涉及 I/O 的操作,如有复杂的layout布局、频繁的I/O操作。

2、应用在主线程上进行长时间的计算,如一些耗时操作。

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

4、主线程处于阻塞状态,为发生在另一个线程上的长操作等待同步的块。

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

2. 发生ANR的原因:

1、主线程存在耗时操作:主线程阻塞(Blocked)、挂起(suspend)、死锁、死循环、耗时操作等;

2、cpu资源被抢占:其他进程某一时间点cpu占比高、某一刻系统的cpu占比过高,都会导致这一时间段无法抢到cpu时间片;

3、主线程卡在binder通信的对端:需要通过binderinfo查看对端信息;

4、系统或者应用自身可用内存紧张:系统一直在执行lowmemorykiller操作查杀进程;

5、应用频繁crash:包括应用自身也容易导致前台应用出现anr的现象;

6、应用内存泄露;

7、系统原因导致:如冻结、温度过高、多媒体(音视频、编解码)、包管理、Block I/O、底层服务NE(native crash)、watchdog、内存黑洞、芯片能力等。



3. 分析日志思路

首先在android(system)日志中搜索“ANR in”关键字,通过此关键字主要查看

1、发生ANR的应用进程、pid、类型;

2、cpu负载、内存压力、cpu使用情况等。

以上是中国农业银行应用的主线程trace日志,主线程在执行native方法,调用到nSyncAndDrawFrame说明进行GPU渲染的过程中出现耗时操作。

说明:以上分析日志的顺序纯属个人喜好,分析步骤可以因人而异。



4. CPU使用率信息分析

从android(高通平台在android.txt,MTK平台在system*.txt)日志中,查看系统中各个进程的cpu使用率,首先关注的进程就是发生anr的进程、system_server、kswapd0、kworker和其他占比较高的进程、以及最终统计的整体cpu使用率信息。例如,如果kswapd0占比较高,就说明内存存在一定的压力;iowait很高就说明系统在一些I/O耗时操作,就可以结合上下文日志及系统日志辅助分析发生ANR的原因。如果很多进程的cpu使用率普遍较高,发生anr应用的cpu使用率较低,此时可以怀疑发生anr的应用拿不到cpu时间片导致anr等。

5. Memory角度分析

查看发生anr时间点前后的可用内存情况,以及系统查杀应用的频繁程度。



6. kernel日志分析思路

在日志中直接搜索关键字“lowmemorykiller”、“iowait”等,查看发生的时间点与发生anr的时间点是否基本对应。如果发生anr时间点附近,出现大量的lowmemorykiller日志信息,则说明当时内存已经严重紧张,可以较大概率认为是内存不足导致后台一直在查杀进程,同时影响前台应用的操作,导致前台应用操作耗时出现anr问题;如果出现iowait,则表示可能出现了I/O卡顿。



7. 综合系统功能进行整体分析

部分情况下,根据trace日志很难能够直接确定发生anr的原因,需要根据当时的系统运行情况进行辅助分析。综合当前的系统环境,可以从消息队列、系统可用内存、发热功耗、后台GC频率和时长、dex2oat耗时、冻结、频繁crash、温度过高、lowmemorykiller、root权限、system.err、system.out、binder_sample、slow operation等角度在日志中搜索关键字进行分析。也存在这种情况,系统日志信息不足以分析出anr的问题,此时需要借助日志中的systrace日志进行详细分析,虽然说大部分时间都对不上,但是也存在对上的时候。

总之,ANR问题需要进行整体分析,结合系统中的所有关键信息共同得出发生ANR的准确结论。

四、目前遇到的典型实例

1. Block I/O

2. GPU渲染

3. 应用适配sdk

4. 相机模块遇到的问题

5. 音频模块遇到的问题

6. APK签名认证

7. 无焦点窗口

8. 内存泄漏

9. Binder耗尽

10. barrier阻塞

11. 消息过量

12. 内存不足

13. 应用死锁

14. MessageQueue

此种问题原因比较多:无焦点窗口导致应用无法响应进一步操作,出现messagequeue堆栈;多次binder通信,每次时长都较短;应用dump进程trace靠后,此时进程已经恢复;应用一直进行消息处理过程。

下面只是针对一种情况进行具体分析:这种情况很有可能是该进程的其他子线程消耗CPU资源导致,这就需要分析其他子线程的trace以及主线程在anr前后打印出的日志。一般情况可以通过分析top占比的子线程trace日志得出结论。

15. 自身NE导致

16. 权限拦截

17. 多媒体编码

18. provider问题

19. park锁耗时

20. cpu时间片不足

21. 空进程

22. 芯片性能不足

五、总结

通过以上的实例剖析,可以看出,除了正常的接收处理超时外,也会有其他额外因素引发应用产生ANR,比如系统的kswapd0过高引发频繁的内存交换、cpu占比过高导致无法获取足够的时间片、binder资源耗尽无法及时通讯等,这些都可以从系统日志中获取到。所以如果单凭trace日志无法分析出来的时候,我们要尽可能多的查看影响发生anr的因素,搜索关键字帮我们快速定位发生的anr问题;另外也可以通过查看日志中的systrace日志或者其他辅助信息来定位问题。总之,解决此类问题,需要有更多的系统洞察能力。

长按关注

内核工匠微信

Linux 内核黑科技 | 技术文章 | 精选教程

  • 15
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

内核工匠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值