赞
踩
一、概述
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、内存黑洞、芯片能力等。
首先在android(system)日志中搜索“ANR in”关键字,通过此关键字主要查看
1、发生ANR的应用进程、pid、类型;
2、cpu负载、内存压力、cpu使用情况等。
以上是中国农业银行应用的主线程trace日志,主线程在执行native方法,调用到nSyncAndDrawFrame说明进行GPU渲染的过程中出现耗时操作。
说明:以上分析日志的顺序纯属个人喜好,分析步骤可以因人而异。
从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时间点前后的可用内存情况,以及系统查杀应用的频繁程度。
在日志中直接搜索关键字“lowmemorykiller”、“iowait”等,查看发生的时间点与发生anr的时间点是否基本对应。如果发生anr时间点附近,出现大量的lowmemorykiller日志信息,则说明当时内存已经严重紧张,可以较大概率认为是内存不足导致后台一直在查杀进程,同时影响前台应用的操作,导致前台应用操作耗时出现anr问题;如果出现iowait,则表示可能出现了I/O卡顿。
部分情况下,根据trace日志很难能够直接确定发生anr的原因,需要根据当时的系统运行情况进行辅助分析。综合当前的系统环境,可以从消息队列、系统可用内存、发热功耗、后台GC频率和时长、dex2oat耗时、冻结、频繁crash、温度过高、lowmemorykiller、root权限、system.err、system.out、binder_sample、slow operation等角度在日志中搜索关键字进行分析。也存在这种情况,系统日志信息不足以分析出anr的问题,此时需要借助日志中的systrace日志进行详细分析,虽然说大部分时间都对不上,但是也存在对上的时候。
总之,ANR问题需要进行整体分析,结合系统中的所有关键信息共同得出发生ANR的准确结论。
四、目前遇到的典型实例
4. 相机模块遇到的问题
6. APK签名认证
9. Binder耗尽
此种问题原因比较多:无焦点窗口导致应用无法响应进一步操作,出现messagequeue堆栈;多次binder通信,每次时长都较短;应用dump进程trace靠后,此时进程已经恢复;应用一直进行消息处理过程。
下面只是针对一种情况进行具体分析:这种情况很有可能是该进程的其他子线程消耗CPU资源导致,这就需要分析其他子线程的trace以及主线程在anr前后打印出的日志。一般情况可以通过分析top占比的子线程trace日志得出结论。
19. park锁耗时
五、总结
通过以上的实例剖析,可以看出,除了正常的接收处理超时外,也会有其他额外因素引发应用产生ANR,比如系统的kswapd0过高引发频繁的内存交换、cpu占比过高导致无法获取足够的时间片、binder资源耗尽无法及时通讯等,这些都可以从系统日志中获取到。所以如果单凭trace日志无法分析出来的时候,我们要尽可能多的查看影响发生anr的因素,搜索关键字帮我们快速定位发生的anr问题;另外也可以通过查看日志中的systrace日志或者其他辅助信息来定位问题。总之,解决此类问题,需要有更多的系统洞察能力。
长按关注
内核工匠微信
Linux 内核黑科技 | 技术文章 | 精选教程
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。