ANR 分析思路淺析


一、引言

      ANR問題是android中常見且令人頭疼的問題,相當多的時候不易直接分析出原因。

 

二、ANR的定義     

     下面先看下百度百科給ANR的定義:

      ANR問題常因在main(主線程)線程執行了復雜耗時的操作,比如文件IO、網絡訪問、無限循環等,最終無奈地被系統拋出ANR。

 

三、ANR的一般分析思路

      1) 從手機的/data/traces/目錄導出traces.txt文件;

      2) 從traces.txt文件獲取ANR產生的時間點T1;

      3) 從traces.txt文件獲取main線程的運行狀態、調用棧;

      4) 查看logcat日志,搜索"ANR in",找出ANR產生的時間點T2,以及時間點T2 前后幾秒鍾,在系統中運行的各進程CPU耗時占比;

      5) 在步驟4)找出目標進程的cpu耗時占比,確認是user占比高,還是kernel占比高,還是iowait占比高;

      6) 根據時間點T1、時間點T2,校准ANR產生的時間范圍 [T1, T2] 或 [T2, T1];

      7) 查看logcat日志,將日志定位到步驟2)中獲取的時間點 [T1, T2] 或 [T2, T1]附近;

      8) 查看logcat日志在時間點 [T1, T2] 或 [T2, T1]附近前后2分鍾的日志,以還原ANR產生前后的場景;

      9) 根據以上步驟得出的信息,定位代碼中可能的問題代碼塊;

      10) 解決問題,或提出階段分析結論。

 

四、ANR的分析示例

       產生ANR后,系統會在/data/traces/下生成traces.txt文件,我們首先將該traces.txt文件從手機對應的目錄導出。

      打開traces.txt后,先確認產生ANR的進程及ANR產生時間,如下圖紅框所示,產生ANR的進程是cn.evergrande.it.phone,ANR產生的時間是2018-08-16 10:34:43

注意,在ANR分析中,ANR產生的時間點非常重要,是串接traces.txt和logcat相關日志線索的連接線,是推理ANR產生原因的重要線索。

 

   繼續分析traces.txt,找到cn.evergrande.it.phone進程的main線程調用棧快照,如下圖所示,main線程在2018-08-16 10:34:43處於Runnable狀態,並且正在

執行java層代碼以測量layout布局中的RecylerView。

  查看logcat日志,搜索"ANR in",定位到如下圖所示的CPU usage from 35958ms to 0ms ago部分的日志,可知 2018-08-16 10:34:07.5462018-08-16 10:34:43.504 時間段,cn.evergrande.it.phone進程並沒有較多的cpu占比。

   繼續查看CPU usage from 372ms to 893ms later部分的日志,可知在 2018-08-16 10:34:43.8772018-08-16 10:34:44.398 時間段,ANR問題開始出現,

其中cn.evergrande.it.phone進程的grande.it.phone、HDLogicThread-2、ReqTimer三個線程的cpu占比都比較高,可推斷是cn.evergrande.it.phone進程引發了ANR。

 

     綜合上述ago、later兩部分的ANR日志,基本可以斷定ANR產生的源頭是cn.evergrande.it.phone進程,

       其中,線程grande.it.phone的線程id是20974、HDLogicThread-2的線程id是21000,ReqTimer的線程id是20974,而在traces.txt中,main的線程id是20974,所以可斷定是

cn.evergrande.it.phone進程阻塞引發了ANR。

  接下來要確認ANR產生的原因,先校准ANR產生的時間點,

  1) traces.txt給出的時間點是 2018-08-16 10:34:43

  2) logcat給出的時間范圍是  2018-08-16 10:34:43.877 到 2018-08-16 10:34:44.398

   綜合1)、2)時間(點)的交集,校准后的ANR產生時間范圍是 2018-08-16 10:34:43.877 到 2018-08-16 10:34:44.398。

  接下來,查看logcat在 2018-08-16 10:34:43.877 到 2018-08-16 10:34:44.398范圍的日志,還原ANR產生時的情景。

  上圖日志顯示了logcat在 2018-08-16 10:34:43.877 到 2018-08-16 10:34:44.398附近的日志,可還原出此時間段系統正在播放音樂、用戶正在操作進度條控制音樂的播放,

但並沒有與ANR產生原因相關的線索,由於traces.txt是在main線程Runnable時生成的,所以不能從main的調用棧分析出ANR產生的可能原因。

 

五、小結

  第四節中舉的示例是沒有足夠數據,以分析出產生ANR的原因,但本文旨在告訴讀者一種分析ANR的思路,以供大家借鑒和不斷完善。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM