The Android Developer Challenge is back! Submit your idea before December 2.

logcat を使用したログの出力と確認

Android Studio の [Logcat] ウィンドウには、ガベージ コレクションが行われたタイミングなどのシステム メッセージに加え、Log クラスを使用してアプリに追加したメッセージも表示されます。メッセージはリアルタイムで表示され、履歴が保持されるため古いメッセージも確認できます。

フィルタの作成、メッセージに表示する情報量の変更、優先レベルの設定、アプリコードにより生成されたメッセージのみの表示、ログの検索を行うことで、注目する情報のみを表示できます。デフォルトでは、logcat には直近に実行したアプリに関するログ出力のみが表示されます。

アプリが例外をスローすると、logcat にはメッセージに続いて、関連するスタック トレースが表示され、これにはコード行へのリンクも含まれます。

Android Studio 2.2 では、[Run] ウィンドウに現在実行中のアプリのログメッセージも表示されます。logcat の出力表示は設定が可能ですが、[Run] ウィンドウの設定はできません。

アプリのログを表示する

アプリのログメッセージを表示するには:

  1. デバイスでアプリをビルドして実行します。
  2. [View] > [Tool Windows] > [Logcat](または、ツール ウィンドウ バーの [Logcat] )をクリックします。

[Logcat] ウィンドウには、図 1 に示すように、ウィンドウ上部のプルダウン リストで選択したアプリのログメッセージが表示されます。

図 1. [Logcat] ウィンドウ

デフォルトでは、logcat はデバイスで実行中のアプリのログメッセージのみを表示します。このデフォルトを変更するには、logcat のメッセージをフィルタリングする方法をご覧ください。

logcat のツールバーには、次のボタンがあります。

  1. logcat のクリア : クリックすると、表示されているログがクリアされます。
  2. 終端までスクロール : クリックすると、ログの一番下にジャンプし、最新のログメッセージが表示されます。その後、ログ内の行をクリックすると、その時点でビューのスクロールが一時停止します。
  3. スタック トレースを上に移動 、スタック トレースを下に移動 : クリックすると、ログ内のスタック トレースを上下に移動できます。出力された例外の後続のファイル名が選択され、エディタ内での対応する行番号が表示されます。これは、ログ内のファイル名をクリックしたときと同じ動作です。
  4. ソフトラップの使用 : クリックすると改行が有効になり、水平スクロールが無効になります(ただし、改行不可の文字列には水平スクロールが必要です)。
  5. 印刷 : クリックすると、logcat メッセージが印刷されます。表示されるダイアログで印刷設定を選択した後、PDF への保存を選択することもできます。
  6. 再起動 : クリックすると、ログがクリアされ、logcat が再起動されます。logcat のクリアボタンとは異なり、このボタンは以前のログメッセージを回復して表示するため、logcat が応答しなくなり、ログメッセージを失いたくない場合に役立ちます。
  7. logcat ヘッダー : クリックすると、[Configure Logcat Header] ダイアログが開き、日時を表示するかどうかなど、各 logcat メッセージの外観をカスタマイズできます。
  8. スクリーン キャプチャ : クリックすると、スクリーンショットがキャプチャされます。
  9. スクリーン レコード : クリックすると、デバイスの画面の動画が記録されます(最大 3 分間)。

ログメッセージを書き込む

Log クラスを使用すると、logcat に表示されるログメッセージを作成できます。通常、以下のログメソッドを使用します。優先度の高いものから順に示しています(下にいくほど詳細)。

オプションの一覧については、Log クラスの説明をご覧ください。

開発時を除き、詳細ログをアプリにコンパイルすべきではありません。デバッグログはコンパイルはされますが、ランタイムには取り除かれます。一方、エラー、警告、および情報のログは常に保持されます。

各ログメソッドでは、1 つ目のパラメータに一意のタグを、2 番目のパラメータにメッセージを指定する必要があります。システム ログメッセージのタグは、メッセージの発信元であるシステム コンポーネントを示す短い文字列です(例: ActivityManager)。独自のタグには、現在のクラスの名前など、役立つと考えられる任意の文字列を使用できます。

クラス内で TAG 定数を宣言して 1 つ目のパラメータに使用するのが一般的であり、推奨されます。たとえば、次のように情報ログメッセージを作成します。

Kotlin

    private const val TAG = "MyActivity"
    ...
    Log.i(TAG, "MyClass.getView() — get item number $position")
    

Java

    private static final String TAG = "MyActivity";
    ...
    Log.i(TAG, "MyClass.getView() — get item number " + position);
    

注: 23 文字を超えるタグ名は、logcat 出力では切り捨てられます。

logcat メッセージの形式

すべての Android ログメッセージには、タグと優先度が関連付けられています。システム ログメッセージのタグは、メッセージの発信元であるシステム コンポーネントを示す短い文字列です(例: ActivityManager)。独自のタグには、現在のクラスの名前など、役立つ任意の文字列を使用できます。次の例では、Log メソッド呼び出しでタグを定義しています。

Kotlin

    Log.d(tag, message)
    

Java

    Log.d(tag, message);
    

優先度は、次のいずれかの値です。

  • V: Verbose(最も低い優先度)
  • D: Debug
  • I: Info
  • W: Warning
  • E: Error
  • A: Assert

ログメッセージの形式は次のとおりです。

    date time PID-TID/package priority/tag: message
    

たとえば、次のログメッセージは、優先度が V で、タグ AuthZen が含まれています。

    12-10 13:02:50.071 1901-4229/com.google.android.gms V/AuthZen: Handling delegate intent.
    

PID はプロセス ID の略で、TID はスレッド ID の略です。スレッドが 1 つしか存在しない場合、これらは同一になることがあります。

ログレベルを設定する

ログレベルを設定することで、logcat に表示されるメッセージの量を制御できます。すべてのメッセージを表示することも、特に重大な問題に関するメッセージのみを表示することも可能です。

ただし、ログレベルの設定とは関係なく、logcat ではすべてのメッセージが収集されます。この設定は、logcat で表示される内容を制御するだけです。

ログレベル メニューで、次のいずれかの値を選択します。

  • Verbose: すべてのログメッセージを表示します(デフォルト)。
  • Debug: 開発時にのみ役立つデバッグ ログメッセージ、およびこのリストでこれより下にあるレベルのメッセージを表示します。
  • Info: 通常の使用で発生するログメッセージ、およびこのリストでこれより下にあるレベルのメッセージを表示します。
  • Warn: エラーとは言えない潜在的な問題、およびこのリストでこれより下にあるレベルのメッセージを表示します。
  • Error: エラーを引き起こした問題、およびこのリストでこれより下にあるレベルのメッセージを表示します。
  • Assert: 開発者にとって絶対に発生してはいけない問題を表示します。

logcat メッセージを検索する

現在 logcat に表示されているメッセージを検索するには:

  1. 正規表現検索パターンを使用する場合は、[Regex] を選択します(任意)。
  2. 検索フィールド に文字列を入力します。

    logcat の表示が、検索条件に応じて変わります。

  3. Enter キーを押すと、現在のセッションの間は検索文字列がメニューに保存されます。
  4. 検索を繰り返すには、検索メニューからこの文字列を選択します。必要に応じて、[Regex] を選択または選択解除します(この設定は記憶されません)。

logcat メッセージをフィルタする

ログ出力を扱いやすいレベルまで削減する方法の 1 つとして、フィルタによる出力の制限があります。

注: フィルタは、現在 logcat に表示されているメッセージにではなく、logcat 履歴全体に適用されます。その他の表示オプションが適切に設定されていることを確認して、調査対象のフィルタ出力が表示されるようにしてください。

フィルタを定義および適用するには:

  1. フィルタ メニューで、フィルタ オプションを選択します。
    • Show only selected application: アプリコードにより生成されたメッセージのみを表示します(デフォルト)。logcat では、アクティブなアプリの PID を使用してメッセージをフィルタリングします。
    • No Filters: フィルタを適用しません。logcat では、選択しているプロセスとは関係なく、デバイスからのすべてのログメッセージを表示します。
    • Edit Filter Configuration: カスタム フィルタを作成または変更します。たとえば、同時に 2 つのアプリからのログメッセージを表示するフィルタを作成できます。

    フィルタを定義した後は、それらをメニューから選択することも可能です。フィルタをメニューから除外するには、フィルタを削除します。

  2. [Edit Filter Configuration] を選択した場合は、フィルタを作成または変更します。
    1. [Create New Logcat Filter] ダイアログで、フィルタのパラメータを指定します。
      • Filter Name: 定義するフィルタの名前を入力するか、左ペインで既存のフィルタ名を選択してそのフィルタを変更します。名前には、小文字、アンダースコア、数字のみを含めることができます。
      • Log Tag: タグを指定します(省略可能)。詳細については、logcat メッセージの形式をご覧ください。
      • Log Message: ログメッセージ テキストを指定します(省略可能)。詳細については、logcat メッセージの形式をご覧ください。
      • Package Name: パッケージ名を指定します(省略可能)。詳細については、logcat メッセージの形式をご覧ください。
      • PID: プロセス ID を指定します(省略可能)。詳細については、logcat メッセージの形式をご覧ください。
      • Log Level: ログレベルを選択します(省略可能)。詳細については、ログレベルを設定するを参照してください。
      • Regex: 該当パラメータに正規表現構文を使用する場合は、このオプションを選択します。
    2. [+] をクリックして、左ペインにフィルタ定義を追加します。

      フィルタを削除するには、左ペインでフィルタを選択して、[-] をクリックします。

    3. 完了したら、[OK] をクリックします。

必要なログメッセージが表示されていないと思われる場合は、[No filters] を選択して、特定のログメッセージを検索します。

ガベージ コレクションのメッセージを確認する

ガベージ コレクションのイベントが発生すると、logcat に出力される場合があります。

アプリのメモリについての詳細は、Memory Profiler で確認してください。

Dalvik ログメッセージ

Dalvik では、すべての GC において次の情報が logcat に出力されます(ART では出力されません)。

    D/dalvikvm(PID): GC_Reason Amount_freed, Heap_stats, External_memory_stats, Pause_time
    

例:

    D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms
    
GC_Reason
GC がトリガされた理由とコレクションの種類が示されます。理由には以下が含まれます。
GC_CONCURRENT
ヒープの空き領域がゼロに近づいてきたため、メモリを開放するために行うコンカレント GC です。
GC_FOR_MALLOC
ヒープに空きがない状態でアプリがメモリを割り当てようとしたため発生した GC です。システムではアプリを停止してメモリを回収する必要がありました。
GC_HPROF_DUMP_HEAP
ヒープを分析するための HPROF ファイルの作成リクエストがあったため発生した GC です。
GC_EXPLICIT
gc() の呼び出しなどによる明示的な GC です(必要時には GC が実行されると考え、このような明示的な呼び出しは避けるべきです)。
GC_EXTERNAL_ALLOC
API レベル 10 以下でのみ発生する GC です(これより新しいバージョンでは、すべて Dalvik ヒープに割り当てられます)。対象となるのは外部に割り当てられたメモリです(ネイティブ メモリまたは NIO バイト タイプのバッファに格納されたピクセルデータなど)。
Amount_freed
この GC により回収されたメモリの量。
Heap_stats
ヒープの空き容量の割合、および(ライブ オブジェクト数)/(合計ヒープサイズ)。
External_memory_stats
API レベル 10 以下で外部に割り当てられたメモリ(割り当て済みメモリの量)/(コレクションが発生する限界値)。
Pause_time
ヒープが大きいほど、一時停止時間は長くなります。同時一時停止時間では、コレクションの開始時と終了時間近の 2 つの停止時間が表示されます。

このログメッセージが多数表示されるときは、ヒープの使用率(上記の例では 3571K/9991K の値)の上昇に注目してください。この値が上昇し続ける場合は、メモリリークが発生している可能性があります。

ART ログメッセージ

Dalvik とは異なり、ART では明示的にリクエストされなかった GC についてはログメッセージが記録されません。GC が出力されるのは、それが低速であると見なされた場合のみです。正確には、GC の一時停止時間が 5 ミリ秒を超えた場合、または GC の継続時間が 100 ミリ秒を超えた場合です。アプリが一時停止を検知できるプロセス状態にない場合(アプリがバックグラウンドで起動している状態や、ユーザーが GC の一時停止時間を検知できない状態など)、その GC が低速であると見なされることはありません。明示的な GC はすべてログに記録されます。

ART のガベージ コレクションのログメッセージには、以下の情報が含まれます。

    I/art: GC_Reason GC_Name Objects_freed(Size_freed) AllocSpace Objects,
        Large_objects_freed(Large_object_size_freed) Heap_stats LOS objects, Pause_time(s)
    

例:

    I/art : Explicit concurrent mark sweep GC freed 104710(7MB) AllocSpace objects,
        21(416KB) LOS objects, 33% free, 25MB/38MB, paused 1.230ms total 67.216ms
    
GC_Reason
GC がトリガされた理由とコレクションの種類が示されます。理由には以下が含まれます。
Concurrent
アプリのスレッドを停止させないコンカレント GC です。この GC はバックグラウンド スレッドで実行されるため、割り当ての妨げにはなりません。
Alloc
ヒープにほとんど空きがない状態でアプリにメモリを割り当てようとしたため発生した GC です。この場合、ガベージ コレクションは割り当てスレッドで発生しています。
Explicit
アプリにより明示的にリクエストされた GC です(例: gc() または gc() の呼び出しによるリクエスト)。ART でも Dalvik と同様に、GC は自動処理に委ね、明示的な GC リクエストは極力避けることをおすすめします。明示的な GC は、割り当てスレッドをブロックし、不必要に CPU サイクルを浪費するため、推奨されません。明示的な GC が別のスレッドより優先された場合は、不自然な動き(滑らかさに欠ける、振動する、アプリが停止するなど)の原因になる可能性があります。
NativeAlloc
Bitmaps や RenderScript 割り当てオブジェクトなど、ネイティブ割り当てによるネイティブ メモリ負荷が原因で発生した GC です。
CollectorTransition
ヒープ遷移が原因の GC です。ヒープ遷移は実行時に GC 戦略が切り替わることで発生します(アプリの一時停止検知の状態が変化したときなど)。コレクターの遷移では、フリーリストで管理されたスペースからバンプポインタ スペースへ(またはその逆)すべてのオブジェクトがコピーされます。

コレクターの遷移が発生するのは、Android 8.0 以前の RAM の少ないデバイスでアプリの処理状態が一時停止を検知できる状態(アプリがフォアグラウンドにある状態や、ユーザーが GC の一時停止を検知できる状態など)から検知できない状態に変わった場合(またはその逆)のみです。

HomogeneousSpaceCompact
ホモジニアス スペース コンパクションは、フリーリスト スペースからフリーリスト スペースへのコンパクションです。これは、通常アプリが一時停止を検知できない処理状態に遷移した場合に発生します。これを行う主な理由は、RAM 使用量の削減とヒープの断片化の解消です。
DisableMovingGc
これは実際には GC の理由ではありませんが、コンカレント ヒープ コンパクションの実行中に GetPrimitiveArrayCritical の使用によってガベージ コレクションがブロックされていたことの通知です。GetPrimitiveArrayCritical を使うとコレクターの動作が抑制されるため、通常は使用しないことを強く推奨します。
HeapTrim
これは GC の理由ではありませんが、ヒープの削減が完了するまでガベージ コレクションがブロックされていたことの通知です。
GC_Name
ART には、実行可能なさまざまな種類の GC があります。
Concurrent mark sweep (CMS)
イメージ スペース以外のすべてのスペースを回収するヒープ全体のコレクターです。
Concurrent partial mark sweep
イメージと Zygote のスペース以外のすべてのスペースを回収する、ヒープの大部分を対象としたコレクターです。
Concurrent sticky mark sweep
最後の GC 以降に割り当てられたオブジェクトのみを開放可能な世代別コレクターです。このガベージ コレクションは高速で一時停止が少ないため、完全または部分的なマーク&スイープよりも頻繁に実行されます。
Marksweep + semispace
ヒープの遷移およびホモジニアス スペース コンパクションに使用される、コンカレント型ではない Copying GC です。
Objects_freed
ラージ オブジェクト スペース以外で、この GC によって回収されたオブジェクトの数。
Size_freed
ラージ オブジェクト スペース以外で、この GC によって回収されたバイト数。
Large_objects_freed
ラージ オブジェクト スペース内で、この GC によって回収されたオブジェクトの数。
Large_object_size_freed
ラージ オブジェクト スペース内で、この GC によって回収されたバイト数。
Heap_stats
空き領域の割合、および(ライブ オブジェクト数)/(合計ヒープサイズ)。
Pause_time(s)
一般的に、一時停止時間は、GC の実行中に変更されたオブジェクト参照の数に比例します。現在、ART CMS GC のみ、GC の終了間近に 1 回一時停止します。Moving GC の一時停止時間は長く、GC 期間の大半にわたります。

logcat で多数の GC が確認された場合は、ヒープの使用率(上記の例では 25MB/38MB の値)の上昇に注目してください。この値が上昇し続け、減少する傾向が見られない場合は、メモリリークが発生していると考えられます。または、「Alloc」が原因で GC が発生している場合は、ヒープ容量の上限が近づいているため、近い将来に OOM 例外が発生すると予想されます。