深入浅出理解ANR

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

ANR 对话框会为用户提供强行退出应用的选项。

深入浅出理解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,此问题属于应用未适配sdk。

产生ANR的原因

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

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

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

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

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

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

发生ANR的原因

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

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

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

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

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

  6. 应用内存泄露;

  7. 系统原因导致:如冻结(freeze)、温控策略(horae、thermalControlUtils)、多媒体(音视频、解码)、包管理、Block I/O(balance_dirty_pages_ratelimited等)、相机服务挂掉等。

分析日志思路

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

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

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

深入浅出理解ANR

event日志:

深入浅出理解ANR

trace日志:

深入浅出理解ANR

深入浅出理解ANR

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

CPU占比信息分析

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

Memory角度分析

可以搜索关键字“Athena”,查看发生anr时间点前后的可用内存情况,以及系统查杀应用的频繁程度。也可以查看日志文件中dumpsys_mem.txt文档查看详细信息。需要注意时间点一致。

深入浅出理解ANR

kernel日志分析思路

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

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

大部分情况根据trace日志很难能够直接确定发生anr的原因,需要根据当时的系统运行情况进行辅助分析。综合当前的系统环境,可以从阻塞消息队列(ANR_LOG 、MessageQueue)、系统可用内存(Athena)、发热功耗(horae(MTK)、system_server(QCOM))、后台GC频率(GC)、dex2oat耗时(dex2oat)、冻结(ColorHansManager或OplusHansManager)、频繁crash(fatal、am_crash)、限频、温控策略(ThermalControlUtils)、lowmemorykiller(kernel日志)、root权限(银行类应用)、system.err、system.out、binder_sample情况等日志进行分析问题。也存在这种情况,系统日志信息不足以分析出anr的问题,此时需要借助日志中的systrace日志进行详细分析,虽然说大部分时间都对不上,但是也存在对上的时候。

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

目前项目中的典型实例

Block I/O

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

gms频繁冻结导致chrome发生ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

冻结导致

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

GPU渲染

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

对端被冻结

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

应用适配sdk

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

相机问题

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

限频导致负载高

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

音频问题

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

APK签名认证

深入浅出理解ANR

深入浅出理解ANR

无焦点窗口

深入浅出理解ANR

深入浅出理解ANR

频繁崩溃

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

内存泄露

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

Binder耗尽

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

barrier阻塞

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

消息过量

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

内存不足

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

应用死锁

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

窗口检查

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

MessageQueue

这种情况很有可能是该进程的其他子线程消耗CPU资源导致,这就需要分析其他子线程的trace以及主线程在anr前后打印出的日志。一般情况分析top占比的子线程trace。

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

自身NE导致ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

wifi权限拦截

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

mediacodec进程大量vpp bypass模式fail

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

Google库导致

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

provider问题

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

park锁耗时

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

深入浅出理解ANR

GMS TIME_SET广播超时

深入浅出理解ANR

深入浅出理解ANR

总结

通过以上的实例剖析,可以看出除了正常的接收处理超时外,也会有其他额外因素引发应用产生ANR,比如系统的kswapd0过高引发频繁的内存交换、cpu占比过高导致无法获取足够的时间片、binder资源耗尽无法及时通讯等,这些都可以从系统日志中获取到。所以如果单凭trace日志无法分析出来的时候,我们要尽可能多的查看影响发生anr的因素,搜索关键字帮我们快速定位发生的anr问题。对于一些日志不全的,只能寻求测试同事帮忙复现,抓取现场完整有效日志进一步分析。解决此类问题,需要有更多的系统洞察能力。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程

Android稳定性相关