ある記事では、ANR例外のキャプチャと分析の方法を簡単に取得する方法を説明しています

1.ANR生成の原則

ANRのトリガー原因については、公式Android開発者向けドキュメントの「WhatTriggers ANR?」に、次のような紹介があります。

通常、アプリケーションがユーザー入力に応答できない場合、システムはANRを表示します。たとえば、アプリケーションがUIスレッドでのI / O操作(多くの場合、ネットワークアクセス)をブロックして、システムが着信ユーザー入力イベントを処理できない場合です。または、アプリが複雑なメモリ内構造を構築したり、UIスレッドでゲームの次の動きを計算したりするのに時間がかかりすぎる可能性があります。これらの計算が効率的であることを確認することは常に重要ですが、最も効率的なコードでさえ実行には時間がかかります......

つまり、ANRを生成する一般的な状況は2つあります。

入力イベント(キーストロークや画面タッチイベントなど)は5秒以内に応答しません。

BroadcastReceiverは10秒以内に実行を完了しませんでした。

Android関連のソースコードの分析と組み合わせると、入力イベントのANR検出は、入力イベント自体によって駆動されることがわかります。システムでは、各入力イベントがアプリプロセスで処理された後、イベントが処理されたことをシステムプロセスに通知して、アプリが応答しないかどうかを判断する必要があります。

ANRを生成するには、少なくとも2つの入力イベントが必要です。シナリオは次のとおりです。

最初の入力イベントが生成され、システムはそれを現在ユーザーが操作しているアプリに送信します。

システムは2番目のイベントを受信し、最初の入力イベントの現在の送信時間が0.5秒を超えた後、処理されていないことを検出し、タイマーを設定して5秒後にトリガーします。

5秒後、システムが最初の入力イベントへの応答がまだないことを検出すると、ANRをトリガーし、アプリのSignal Catherスレッドをアクティブにしてtraces.txtを生成し、ANRダイアログボックスをポップアップして、アプリが応答していないことをユーザーに通知します。

つまり、ANRを生成するには、最初の入力イベントを処理してシステムに5.5秒以上フィードバックしてはならず、2番目の入力イベントを生成する必要があります。2番目の入力イベントがない場合、最初の入力イベントが60秒以上実行されても、ANRは生成されません。

2.ANRログ生成の原則

システムのsystem_serverプロセスは、アプリにANRがあることを検出すると、SIGQUIT(シグナル3)シグナルをANRプロセスに送信します。通常の状況では、システムlibart.soは信号を受信し、Java仮想マシンのdumpメソッドを呼び出してトレースを生成します。

Umeng +を例にとると、SDKはSIGQUITをインターセプトします。ANRが発生すると、libcrashsdk.soは最初に信号を受信し、トレースとANRログを生成します。SDKが信号を処理した後、引き続き信号をシステムのlibart.soに渡し、システムがANRtraces.txtを生成できるようにします。

次の図に示すように、赤い線はU-APM SDKがANR信号を処理してANRログを生成するプロセスであり、紫色の線はシステムによってANRtraces.txtを生成するプロセスです。

ANRキャプチャの原則

その中で、SDKがトレースを生成するとき、libart.soのdumpメソッドを使用し、生成されるコンテンツは基本的に元のシステムと同じです。さらに、U-APM SDKは、dumpメソッドを呼び出すときに最適化されます。ダンプ速度は、ネイティブトレースを生成するシステムの速度よりも大幅に高速であるため、system_serverがSIGKILL(シグナル9)を使用してトレースを長時間生成する可能性を効果的に回避できます。殺します。

すべてのスレッドのトレース情報を取得した後、完全なANRログが生成され、ANRを取得する理由、携帯電話のTOPプロセスのCPU使用率、ANRプロセスのTOPスレッドのCPU使用率、各CPUコアの処理時間分布、およびディスクも提供されます。 IO操作の待機時間などの重要な情報。

現在、SDKによって生成されるANRログ情報には、基本的にシステムによって生成されるANRログのすべてのコンテンツが含まれ、システムログにないコンテンツや、アプリによって追加される独自のビジネス関連情報も含まれます。これは、ANRの問題の分析、配置、および解決に役立ちます。より強力なサポートを提供します。

3.ログ分析

SDKまたはSDKが接続されると、ANRログが自動的に有効になります。ANRが発生すると、システムの前にANRログが生成されます。ログの主な内容は次のとおりです。

1)。ANRログ構造

ログ分析プラグインを使用すると、次のように、生成されたANRログに含まれるコンテンツと重要な情報を明確に確認できます。

ANRログ構造

生成されたログがセクションごとに複数のセクションに分割されている場合を除き、重要な情報を含むセクションは赤でマークされ、特に重要な情報は太字で示されます。さらに、各セクションには、対応する位置に直接ジャンプするためのショートカットキーがあります。

2)。ANRの概要

要約情報は次のとおりです。

ANR要約情報

コンテンツのこの部分は、主にシステムから取得されます。これには、ANRのプロセス名、ANRが生成された時刻、ANRの理由、およびANRの前後数秒以内のシステムのTOPプロセスのCPU使用率が含まれます。その中で、ANRの理由を使用して、入力イベントの処理タイムアウトなのか、BroadcastReceiverなどの他のメッセージの処理時間が長すぎるのかを知ることができます。CPU使用率は、どのプロセスがCPUリソースを過剰に占有しているかを知ることができます。

3)システムリソースの使用

ANRが発生する前の期間内の平均CPU使用率、CPUコア使用量、および時間のかかる分布、ANRプロセスにおけるTOPスレッドの実行時間と割合、ページ障害の数、ディスクIO操作の待機時間を記録できます。時間などの内容。次のように:

システムリソースの使用

IOがビジー状態でANRが発生している場合、io待機時間とCPU時間の分布におけるiowait時間の割合がより顕著になります。CPU時間分布におけるユーザーとシステムの割合から、ユーザーモードコードの実行に時間がかかりすぎるか、Linuxカーネルかを知ることができます。システム呼び出しに時間がかかりすぎます。

4)。ANRトレース

トレース情報は、ANRログの最も重要なコンテンツです。たとえば、U-APMによって生成されるトレース情報には、メインスレッドのネイティブコールスタックと、ANRが発生したときのすべてのスレッドのJavaコールスタックが含まれます。通常、デッドロックの問題は、コールスタックの情報によって簡単に見つけることができます。

ANRトレース

トレースはforkの子プロセスによって生成され、Java仮想マシンのバグによるトレースの生成時にネイティブクラッシュが発生することはなく、ダンプ中にスタックしたためにANRログ全体の生成がブロックされることもありません。

5)。Logcat

ANR中にAndroidlogcatを取得すると、ROMによって追加されたアクセス許可制御の一部をバイパスして、現在のAppANRの前に関連するログ情報を取得できます。現在のプロセスと現在のエラースレッドによって出力されたログが強調表示され、エラーと警告も目立つ色でマークされます。

logcat

6)メモリなどの他の情報

次のような一連のメモリ情報は、ANRログを介して分析できます。

システムRAMの合計メモリ、残りの使用可能なメモリ。

現在のプロセスが占める仮想メモリと物理メモリ。

Javaが占有する合計メモリと使用可能なメモリ。

ネイティブメモリと使用可能なメモリなど。

さらに、ANRログはJavaおよびネイティブクラッシュログと同じであり、次のようなビジネスカスタムログコンテンツ拡張をサポートします。

クラッシュする前に短いカスタムヘッダー情報を追加します。

クラッシュする前に外部ファイルを登録すると、クラッシュしたときにその内容がログに記録されます。

クラッシュする前に、ビジネスに関連するいくつかの最近の操作または情報をキャッシュします。

クラッシュが発生した場合、ビジネスの最新のコンテンツがコールバックを通じて返されます。

おすすめ

転載: blog.51cto.com/10636575/2585428