この記事では、ANR 分析の一般的な手順をシステムの観点から簡単にまとめます。
1. ANR の紹介
1.1 ANRの定義
ANR (Application Not Responding): アプリケーションが応答していません。ANR は、メイン スレッドがタイムアウト期間内に特定の処理を完了しない場合に発生します。
1.2 ANR の種類
1) KeyDispatchTimeout - キーまたはタッチ イベントの主なタイプ、入力イベントが 5 秒以内に処理されず、ANR
ログ キーワード: 理由: 入力ディスパッチがタイムアウトしました xxxx
2) ServiceTimeout-bind、create、start、unbind などはメインスレッドでの処理に時間がかかる フォアグラウンド Service は 20 秒以内、バックグラウンド Service は 200 秒以内に処理されない ANR ログキーワード: タイムアウト実行 service:/
runningサービスXXX
3) BroadcastTimeout- BroadcastReceiver onReceiver がトランザクションを処理するとき、フォアグラウンド ブロードキャストは 10 秒以内であり、バックグラウンド ブロードキャストは 60 秒以内に処理されません. ANR ログ キーワード: ブロードキャスト
XXX のタイムアウト/タイムアウト中の受信者:XXX/XXX のブロードキャスト
4) ProcessContentProviderPublishTimedOutLocked-ContentProvider パブリッシュが 10 秒以内に処理されず、ANR
ログ キーワード: タイムアウト パブリッシング コンテンツ プロバイダー
1.3 ANR の一般的な原因
- 複雑なレイアウト、巨大な for ループ、IO など、メイン スレッドでの時間のかかる操作。
- メインスレッドは子スレッドによって同期的にブロックされます
- メイン スレッドが Binder ピアによってブロックされている
- バインダーがいっぱいで、メイン スレッドが SystemServer と通信できません
- システム リソース (CPU/メモリ/IO) を取得できません
二、ANR分析
この記事で説明する ANR 分析は、バグレポートの分析です。
最初にバグレポートを取得します。
adb bugreport > bugreport.txt
ANR の分析は、次の手順に大別されます。
1. ANR がいつ発生するかを判断します。キーワード: am_anr、ANR in
2. ANR が発生したときに出力されるトレースを表示します。ファイル ディレクトリ: /data/anr/traces.txt、およびシステム追加情報キーワード: MIUI-BLOCK-MONITOR
3.システムの時間のかかるキーワード:binder_sample、dvm_lock_sample、am_lifecycle_sample、バインダー スレッド
4. ソース コードと上記の情報を組み合わせて分析します
午前 2 時 1 分
12-17 06:02:14.463 1566 1583 I am_anr : [0,8769,com.android.updater,952680005,Broadcast of Intent
anr が発生した時刻 am_anr: プロセス pid: 8769、プロセス名: com.android.updater、ANR のタイプ: BroadcastTimeout、特定のクラスまたは理由: { act=android.intent.action.BOOT_COMPLETED flg=0x9000010 cmp= com.android .updater/.BootCompletedReceiver (エクストラあり) }
2.2 での ANR
am_anr と ANR in を使用して、ANR が発生した時刻、対応するプロセス、理由の説明などを特定し、CPU 使用率と iowait 時間に特別な異常があるものにも注意を払うことができます。
2.3 トレース
ANR が発生すると、各アプリケーション プロセスおよびシステム プロセスの関数スタック情報が /data/anr/traces.txt ファイルに出力されます.ANR が発生したアプリケーション プロセスのメイン スレッドの特定の実行スタックに注意を払うことがよくあります。 . ANR が発生したときにメイン スレッドが何をしているのか、なぜスタックしているのか、ロック、バインダー呼び出し、またはメイン スレッドでの時間のかかる操作を待っているのかなどを知ることができます。
2.4 いくつかのシステム キーワード
binder_sample
: 各プロセスのメイン スレッドのバインダー トランザクションの消費時間を監視し、しきい値 (例: 500ms) を超えると、対応するターゲット コール情報を出力します。
説明します:
1. メイン スレッドは 2754、2.
android.app.IActivityManager インターフェイスを実行、
3. 対応するメソッド コード = 35 (つまり、STOP_SERVICE_TRANSACTION)、
4. 費やされた時間は 2900 ミリ秒、
5. ブロックのパッケージはandroid.process.media.
最後のパラメーターはサンプル比率です (あまり値はありません)
dvm_lock_sample
:ロック待ちスレッドの閉塞時間が閾値(例:500ms)を超えた場合、現在のロック保持状態を出力します。
説明: system_server: ActivityManagerService.java の 6403 行のコードまで実行された Binder_9 は、AMS ロックを待機していました。「-」は、ロックが同じファイルであることを意味します。
つまり、同じファイル内の 1448 行のコードによってロックが保持され、Binder_9 スレッドが 1500 ミリ秒ブロックされます。
am_lifecycle_sample
:メインスレッドでのアプリのライフサイクルコールバックメソッドの実行時間が閾値(例:3000ms)を超えると、該当する情報が出力されます。
説明: pid=8203、processName=com.android.systemui、MessageCode=114(CREATE_SERVICE)、時間がかかる 3.827 秒
注: MessageCode=200 (並列ブロードキャスト onReceive 時間がかかる)、他のコードについては ActivityThread.H クラスを参照
binder thread
:system_serverなどのプロセスのスレッドプールが使い果たされ、アイドルスレッドがない場合、バインダー通信が枯渇状態となり、枯渇状態が一定の閾値を超えた場合に情報が出力されます。
説明: system_server プロセスのスレッド プールが最大 100 ミリ秒の間いっぱいです
上記のバインダー呼び出し情報については、ログでロック情報を探します
PackageManagerService.java No. 3537 が必要とするロックは UserManagerService.java の 3380 行で保持されています. UserManagerService.java の 3380 行をソースコードと合わせて見てみましょう. ロックに時間がかかる原因は何ですか?
注: バインダー呼び出しは時間がかかります. 通信プロセス中のバインダーのビジー状態が原因であるか, ピアがロックを保持しているか時間のかかる操作を実行しているために時間がかかる可能性があります. バインダー呼び出し情報はログに出力され、バインダー呼び出しとリモート エンドの間の通信が終了したことを示します。バインダー呼び出し情報の出現は、フレームワークに問題があることを意味するものではありません。ログ分析。
基本的な分析プロセスを要約します。
- ログからANRの発生過程や発生時刻、おおよその動作を確認し、その際のCPU、メモリ、IOの状況に注意してください。
- トレースを分析し、まず時間が正しいかどうかを確認し、犯罪現場であるかどうかを判断してから、メイン スレッドに時間のかかる、デッドロック、その他のロックなどの問題がないかどうかに注意して、基本的に実行できるようにします。アプリの問題かシステムの問題かを確認してください。
- システムの問題が原因である場合は、binder_sample と dvm_lock_sample を組み合わせて、バインダー呼び出しに時間がかかる問題とシステム ロック保持に時間がかかる問題をそれぞれ特定します。
- コードやソースコードを組み合わせて、問題点を詳細に分析します。
転載:https://www.jianshu.com/p/082045769443