ANR介绍
ANR全名Application Not Responding, 也就是"应用无响应".
ANR产生原因
只有当应用程序的UI线程响应超时才会引起ANR,超时产生一般有两种
- 当前的事件没有机会得到处理,例如UI线程正在响应另外一个事件,当前事件由于某种原因被阻塞
- 当前事件正在处理,但由于耗时太长没能及时完成
ANR分类
从发生的场景分类:
- Input事件超过5s没有被处理完
- Service处理超时,前台20s,后台200s
- BroadcastReceiver处理超时,前台10S,后台60s
- ContentProvider执行超时,比较少见
每部分具体时间定义位置如下
ActivityManagerService.java
// BroadcastReceiver前后台超时
// How long we allow a receiver to run before giving up on it.
static final int BROADCAST_FG_TIMEOUT = 10*1000;
static final int BROADCAST_BG_TIMEOUT = 60*1000;
// 按键分发超时
// How long we wait until we timeout on key dispatching.
static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
// ContentProvider超时
// How long we wait for an attached process to publish its content providers
// before we decide it must be hung.
static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
ActiveServices.java
// Service前后台超时
// How long we wait for a service to finish executing.
static final int SERVICE_TIMEOUT = 20*1000;
// How long we wait for a service to finish executing.
static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
从发生的原因分:
- 主线程有耗时操作,如有复杂的layout布局,IO操作等。
- 被Binder对端block
- 被子线程同步锁block
- Binder被占满导致主线程无法和SystemServer通信
- 得不到系统资源(CPU/RAM/IO)
从进程的角度分:
问题出在当前进程:
主线程本身耗时, 或则主线程的消息队列存在耗时操作;
主线程被本进程的其他子线程所blocked;
问题出在远端进程(一般是binder call或socket等通信方式)
ANR分析
- Mtklog中搜索
anr in
,am_anr
确定发生组件,原因,时间,CPU使用情况,是否IOWait
典型的分析情况
1.如果TOTAL的和接近100,有可能是因为当前使用的app占用的cpu太高,导致系统将你的杀死。
2.如果TOTAL很小,则说明线程被阻塞了,主线程在等待下条消息的进入,任务在等待时anr。
3.如果ioWait很高,则说明是io操作导致的
- traces.txt 中定位
线程中状态
static final Thread.State[] STATE_MAP = new Thread.State[] {
Thread.State.TERMINATED, // ZOMBIE
Thread.State.RUNNABLE, // RUNNING
Thread.State.TIMED_WAITING, // TIMED_WAIT
Thread.State.BLOCKED, // MONITOR
Thread.State.WAITING, // WAIT
Thread.State.NEW, // INITIALIZING
Thread.State.NEW, // STARTING
Thread.State.RUNNABLE, // NATIVE
Thread.State.WAITING, // VMWAIT
Thread.State.RUNNABLE // SUSPENDED
};
native thread有10种状态, 对应着java thread的6种状态.
- 如果主线程耗时,状态为TIMED_WAIT
- 主线程等待子线程的锁,一定时间出现ANR,状态为MONITOR
-wait to lock ....held by tid=11 再搜索tid是11的线程信息
网友评论