ANR原因
1、CPU满负荷,I/O阻塞
2、内存不足,系统分配给一个应用的内存是有上限的,长期处于内存紧张,会导致频繁内存交换,进而导致应用的一些操作超时。自己内存泄漏或者其他应用占用的大量内存
3、四大组件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
三方应用开发常见的anr三种情况前文已经详细呈现,避免anr思路已经清晰,简单总结下:
- 绝对不要在主线程上进行复杂耗时的操作,比如说发送接收网络数据、进行大量计算、操作数据库、读写文件等,统统采用异步操作
2.broadCastReceiver 要进行复杂操作的的时候,可以在onReceive()方法中启动一个IntentService或者JobIntentService去做。
- Service中的耗时操作最好也是采用异步任务
4.在设计及代码编写阶段避免出现出现同步/死锁、死循环等不恰当情况
ANR分析
1、CPU 负载
2、内存信息
从含义可以得出结论: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导出