anr問題的處理技巧
hi, 大家好,我是愛吃香蕉的猴子,今天記錄一下ANR問題的處理套路吧,這也是自己分析ANR問題一般的思路;
- 根據測驗的描述,區分是Monkey測驗偶現的 ,還是可以手動復現,一般情況前者多一些,我也是根據前者寫這個記錄;
- 首先,要會區分ANR型別,是什么型別的ANR ??
- 用戶輸入事件處理超時: KeyDispatchTimeout-主要型別按鍵或觸摸事件,input事件在5S內沒有處理完成發生ANR
- 關鍵字:Reason: Input dispatching timed out xxxx
- Broadcast超時: BroadcastReceiver onReceiver處理事務時前臺廣播在10S內,后臺廣播在60s內沒有處理完成發生ANR
- 關鍵字:Timeout of broadcast XXX/Receiver during timeout:XXX/Broadcast of XXX
- Service超時:ServiceTimeout-bind,create,start,unbind等在主執行緒處理耗時,前臺Service在20s內,后臺Service在200s內沒有處理完成發生ANR
- 關鍵字:Timeout executing service:/executing service XXX
- ContentProvider超時: publish在10s內沒有處理完成發生ANR
-
- 關鍵字:timeout publishing content providers
- 用戶輸入事件處理超時: KeyDispatchTimeout-主要型別按鍵或觸摸事件,input事件在5S內沒有處理完成發生ANR
- 補充一種型別 視窗獲取焦點超時(input 型別的一種子型別)
- 關鍵字:Reason: Input dispatching timed out (Waiting because no window has focus but there is a focused application that may eventually add a window when it finishes starting up.)需要注意區分同為Input dispatching timed out大類的用戶輸入事件處理超時,這兩類超時括號內的提示語是不同的,
- 這個問題,我可以簡單理解為視窗切換時,A --> B, 開始焦點在A 視窗在A ,后面 焦點在A 這時視窗時null,如果這個時候超過了5s,那就會發生anr.
查看現場
- ag “am_anr” / ag ag “ANR in” # 這個時候,你會發現很多或者幾個anr的地方, 我先看時間最早的,我這里就不貼log了
- 確定最早發生的anr的時間,行程,(如果還沒有確定anr型別) 這里基本也會看到特定型別anr的資訊
- 然后既然確定了一個anr的位置,那我們就要分析,這個是怎么造成的?? 猜測思路如下
- 1. 主執行緒耗時操作,如復雜的layout,龐大的for回圈,IO等
- 2. 主執行緒被子執行緒同步鎖block
- 3. 主執行緒被Binder 對端block
- 4. Binder被占滿導致主執行緒無法和SystemServer通信
- 5. 得不到系統資源(CPU/RAM/IO)(有一個關鍵搜索:CPU usage)
- 如果,并沒有有效的識訓,那就檢索 上面的anr型別的關鍵字grep -v ‘mmm|nnn’ abc.txt
看anr的trace檔案 我一般是大概有了了解,最后看trace檔案
- 匹配一下,上面看到的時間 行程 執行緒(如果不匹配,也可以反向去找)
- 補充一下:
- main tid=1 //主執行緒
- group: 執行緒組名稱
- sCount: suspendCount個數
- dsCount: debugSuspendCount個數
- obj: 0x4025b1b8 執行緒java物件地址
- self: 執行緒native的物件地址
- Binder Thread #2: Binder執行緒是行程的執行緒中用來處理binder請求的執行緒.
- SUSPENDED:執行緒暫停,可能是由于輸出Trace、GC或debug被暫停
- NATIVE: 正在執行JNI本地函式
- MONITOR: 執行緒阻塞,等待獲取物件鎖
- WAIT: 執行了無限等待的wait函式
- TIMED_WAIT: 執行了帶有超時引數的wait、sleep或join函式
- VMWAIT: 正在等待VM資源
- RUNNING/RUNNABLE: 執行緒可運行或正在運行
- INITALIZING: 新建,正在初始化,為其分配資源
- STARTING: 新建,正在啟動
- ZOMBIE: 執行緒死亡,終止運行,等待父執行緒回收它
- 一般我們要首先查看main執行緒,是否出現 block wait suspend ,有沒有執行緒間的死鎖,有沒有出現binder呼叫服務端沒有回應,有沒有阻塞在system server.
- 死鎖:執行緒在獲得一個鎖L1的情況下再去申請另外一個鎖L2,也就是鎖L1想要包含了鎖L2,也就是說在獲得了鎖L1,并且沒有釋放鎖L1的情況下,又去申請獲得鎖L2,這個是產生死鎖的最根本原因,看一個android中的簡單Log
Cmd line: com.android.inputmethod.latin
"main" prio=5 tid=1 NATIVE
......
at android.os.BinderProxy.transact(Native Method)
at com.android.internal.view.IInputMethodManager$Stub$Proxy.getCurrentInputMethodSubtype(IInputMethodManager.java:908) ......
Cmd line: system_server
"main" prio=5 tid=1 MONITOR
- waiting to lock <0x41c5a650> (a java.lang.Object) held by tid=12 (WindowManager)......
"WindowManager" prio=5 tid=12 MONITOR
- waiting to lock <0x41c0c118> (a android.view.inputmethod.InputMethodManager$H) held by tid=61 (Binder_F)......
"Binder_F" prio=5 tid=61 MONITOR
at com.android.server.InputMethodManagerService.getCurrentInputMethodSubtype(InputMethodManagerService.java:~3078)
片
- 決議一下:main等待WindowManager ,WindowManager 又等待Binder_F,因此inputmethod主執行緒的遠程呼叫無法回傳,導致ANR,
- 還有一點,這里查看這個cpu占用資訊
11 CPU usage from 9818ms to 0ms ago (2020-12-09 06:03:39.534 to 2020-12-09 06:03:49.352):
12 109% 10198/system_server: 85% user + 24% kernel / faults: 12620 minor 11 major
13 35% 2724/pulseaudio: 34% user + 1.7% kernel
14 13% 10545/com.android.car: 10% user + 3.1% kernel / faults: 3518 minor
............
110 74% TOTAL: 49% user + 24% kernel + 0.1% iowait + 0.1% softirq
- binder呼叫服務端沒有回應: 基本通過clent和server共同的方法去grep,看服務端在做什么?
- system server出現block
- 有時候,也可以根據:id threadid 進行grep看執行了什么程式,例如:1089 1089
- 其實,74%這個是負載,這個負載是算是高,在這個負載的情況出現anr也是有可能是系統性能問題,但不能明確,起碼我們還要找到什么原因造成的負載高,cpu其他行程占用資訊,基本都相對容易判斷,
- 其實還有一些分析策略,但最常用的還是這些套路吧,有了好的且可以分享的案例,我會補充上來,
Code的搬運工V1.0
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/246193.html
標籤:其他
上一篇:關于網上很不好找的幼兒識圖APP
