ANR介紹
ANR全名Application Not Responding, 也就是"應(yīng)用無響應(yīng)".
ANR產(chǎn)生原因
只有當(dāng)應(yīng)用程序的UI線程響應(yīng)超時才會引起ANR,超時產(chǎn)生一般有兩種
- 當(dāng)前的事件沒有機(jī)會得到處理永票,例如UI線程正在響應(yīng)另外一個事件搂捧,當(dāng)前事件由于某種原因被阻塞
- 當(dāng)前事件正在處理驮俗,但由于耗時太長沒能及時完成
ANR分類
從發(fā)生的場景分類:
- Input事件超過5s沒有被處理完
- Service處理超時,前臺20s允跑,后臺200s
- BroadcastReceiver處理超時王凑,前臺10S,后臺60s
- ContentProvider執(zhí)行超時聋丝,比較少見
每部分具體時間定義位置如下
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;
// 按鍵分發(fā)超時
// 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;
從發(fā)生的原因分:
- 主線程有耗時操作索烹,如有復(fù)雜的layout布局,IO操作等弱睦。
- 被Binder對端block
- 被子線程同步鎖block
- Binder被占滿導(dǎo)致主線程無法和SystemServer通信
- 得不到系統(tǒng)資源(CPU/RAM/IO)
從進(jìn)程的角度分:
問題出在當(dāng)前進(jìn)程:
主線程本身耗時, 或則主線程的消息隊列存在耗時操作;
主線程被本進(jìn)程的其他子線程所blocked;
問題出在遠(yuǎn)端進(jìn)程(一般是binder call或socket等通信方式)
ANR分析
- Mtklog中搜索
anr in
,am_anr
確定發(fā)生組件百姓,原因,時間况木,CPU使用情況,是否IOWait
典型的分析情況
1.如果TOTAL的和接近100垒拢,有可能是因為當(dāng)前使用的app占用的cpu太高,導(dǎo)致系統(tǒng)將你的殺死火惊。
2.如果TOTAL很小求类,則說明線程被阻塞了,主線程在等待下條消息的進(jìn)入屹耐,任務(wù)在等待時anr尸疆。
3.如果ioWait很高,則說明是io操作導(dǎo)致的
- traces.txt 中定位
線程中狀態(tài)
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種狀態(tài), 對應(yīng)著java thread的6種狀態(tài).
- 如果主線程耗時,狀態(tài)為TIMED_WAIT
- 主線程等待子線程的鎖仓技,一定時間出現(xiàn)ANR鸵贬,狀態(tài)為MONITOR
-wait to lock ....held by tid=11 再搜索tid是11的線程信息