天天看點

ANR 學習筆記一、理論篇二 、實戰篇

接觸 ANR 分析一段時間了,但在碰到相關問題的時候,總還是有一種生澀感,專門開篇部落格,做一些文章閱讀後的筆記吧,不斷積累。(友情提示:每個藍色字的小标題都是一個連結,可以點選跳轉到大佬的原文。)

一、理論篇

1 Android ANR 的設計原理

ANR被總結為:埋雷、拆雷、爆雷三個步驟。主要内容是結合源碼,分析了 service ANR 的原理,最後的總結我直接複制一下:

1 将要執行的service添加到系統程序的executingServices中。

2 開啟檢測邏輯,檢測将在指定時間後執行,具體時間決定與是前台服務還是背景服務。

3 一旦服務被執行完,就會嘗試移除檢測邏輯。

4 如果檢測邏輯沒被移除,就會被執行,然後去檢測哪個服務發生了ANR。

5 如果發生了ANR,就将建構ANR資訊提供給系統,否則就檢測并執行下一輪ANR檢測。

二 、實戰篇

1 ANR問題該如何分析?

這篇文章極力推薦,雖然是 17 年的,但都是幹貨啊,想精簡一下都難。主要總結了 ANR 日志的分析思路,給的例子也很是經典。

1 ANR 分類

廣播ANR

Service ANR

ContentProvider ANR

Input ANR

面向系統:WatchDog

産生ANR原因,如下幾種:

耗時操作

自身服務阻塞

系統阻塞

記憶體緊張

CPU資源搶占

2 分析思路

ANR 問題應該看哪些日志呢?主要是 Trace 日志、log 日志(推薦順序是 logcat, kernel,cpuinfo 以及 meminfo。

分析 logcat 思路

關鍵字:anr in,low_memory,slow_operation

anr in 顯示故障發生的位置,cpu 使用情況等資訊;

low_memory 是低記憶體相關的列印;

slow_operation 說明系統程序的排程慢。

分析 kernel 思路

關鍵字:lowmemorykiller

該列印是系統在進行清除,很頻繁的話就有可能是記憶體低。Free Memory 是空閑實體記憶體,File Free 是檔案 Cache。當 Free 和Other 整體數值都偏低時,Kernel 會進行記憶體交換,導緻整個系統卡頓。

分析 cpuinfo 思路

如果存在占 CPU 明顯偏高程序,則 ANR 可能和此程序搶占 CPU 有一定關系;

如果 kswapd,emmc 程序在 top 中,則說明遇到系統記憶體壓力或檔案IO開銷。

分析 meminfo 思路

看哪類應用或系統占用記憶體偏高;

如果應用或系統記憶體使用比較正常,但整體記憶體偏低,則說明系統中緩存了大量程序,沒有及時釋放。

3 一些執行個體

主線程進行耗時操作,或被程序内其它線程阻塞

先觀察主線程堆棧,通常會有 blocked 資訊,這類問題從堆棧一般能找到原因。

這裡列了一個等待其他線程 GC 的例子。學會看WaitingForGcToComplete、WaitingPerformingGc 這一對關鍵字,GC 時間長的原因從記憶體使用情況看。

應用内部線程邏輯依賴關系導緻逾時,觸發ANR

這是一個主線程 binder 通信過程中被阻塞的例子。通過看 binder 被調用時的函數名來找到 binder 的對端線程(Binder.java 的下一行),然後看對應線程的狀态,後面就是套娃過程,最終找到了一個 binder 參與的死鎖鍊路。

系統記憶體過低,kernel 進行記憶體交換過程會引起整個系統運作緩慢

主線程Suspend狀态的原因:(1)程序自身過于繁忙,時間片不夠用;(2)系統比較繁忙,低優先級得不到時間片。

從堆棧沒有明顯看到原因,按思路去 logcat 看。

(1) ANR in 。關注了 cpu load 資訊(Load: 22.72 / 20.06 / 15.54 /分别對應1分鐘/5分鐘/15分鐘/)、cpu 占比。發現系統負載大(通常 10 左右)、記憶體偏低。

(2)slow_operation 搜尋發現系統函數執行一次花費時間長;

(3)已經懷疑到是記憶體問題了,是以就直接看 meminfo 了。

Binder 資源耗盡,導緻通信請求難以及時響應

這個問題也是堆棧沒找到有效資訊,去 logcat 找。

根據分析思路的順序找log,發現記憶體沒有問題。根據 anr 程序本身 cpu 占比高懷疑到 cpu 方向。大佬下面的推測就很靈性了,個人感覺很需要經驗。

ANR 學習筆記一、理論篇二 、實戰篇

找到其他線程後,繼續看堆棧,根據最後的調用再回到logcat。

高CPU過度搶占時間片,導緻其它應用或任務難以及時排程

主線程多半是處于空閑或Suspend狀态.

思路還是我們之前說的那個順序,在 anr in 的前後根據 pid 去找有效資訊。然後是在 trace 和 logcat 間反複。

ANR 學習筆記一、理論篇二 、實戰篇

日志不全,缺少Trace或其它日志

簡而言之,就是按分析log的思路,盡量挖掘有效資訊。系統層面無非是 cpu 和 記憶體兩個主要角度。

繼續閱讀