面试:ANR原因及排查

ANR原因

1、CPU满负荷,I/O阻塞

2、本应用内存泄漏或者其他应用占用的大量内存,导致的内存不足,系统分配给一个应用的内存是有上限的,长期处于内存紧张,会导致频繁内存交换,进而导致应用的一些操作超时。

3、KeyDispatchTimeOut、BroadcaseTimeOut、ServiceTimeOut、ContentProviderTimeout导致ANR

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

5、系统服务无法及时响应:比如获取系统联系人等,系统的服务都是Binder机制,服务能力也是有限的,有可能系统服务长时间不响应导致ANR

根据我的经验以下几种情况都会导致ANR

Android ANR分析详解 - 简书

  • CPU密集,导致主线程没法抢占cpu时间片,要注意cpu占用高的进程
  • 高IO,如不当访问数据库导致数据库负载过重时(log中cpu的使用iowait占比高)
  • 低内存(low memory),如内存不足导致block在创建bitmap上
  • 死锁引发ANR,非主线程持有主线程需要的锁对象,导致主线程等待超时,通常log中会有以下字段 Blocked | - locked | waiting to lock | held by thread,这个时候cpu多数是空闲,使用占比很低
  • 当前应用进程进行进程间通信请求其他进程,其他进程的操作长时间没有反馈,例如操作硬件Camera
  • Service binder数量达到上限

三方应用开发如何避免ANR

1、绝对不要在主线程上进行复杂耗时的操作,比如说发送接收网络数据、进行大量计算、操作数据库、读写文件等,统统采用异步操作

2、broadCastReceiver 要进行复杂操作的的时候,可以在onReceive()方法中启动一个IntentService或者JobIntentService去做。

3、Service中的耗时操作最好也是采用异步任务

4、在设计及代码编写阶段避免出现出现同步/死锁、死循环等不恰当情况

ANR分析

1、CPU 负载:adb shell dumpsys cpuinfo

分析cpu usage 信息,查看是哪个进程占用CPU过高

2、内存信息:adb shell dumpsys meminfo

从含义可以得出结论:Free memory until OOME 的值很小的时候,已经处于内存紧张状态。应用可能是占用了过多内存。

3、产生ANR后,看下Log

可以看到logcat清晰地记录了ANR发生的时间,以及线程的tid和一句话概括原因:WaitingInMainSignalCatcherLoop,大概意思为主线程等待异常。 最后一句The application may be doing too much work on its main thread.告知可能在主线程做了太多的工作。

4、ANR异常已经输出到traces.txt文件

/data/anr/traces.txt导出

猜你喜欢

转载自blog.csdn.net/cpcpcp123/article/details/128089185
ANR