logcat を使用してログを書き込み、表示する

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

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

アプリが例外をスローしたときは、メッセージの後に関連するスタック トレース(コード行へのリンクを含む)が表示されます。

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

アプリのログを表示する

アプリのログメッセージを表示する手順は次のとおりです。

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

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

図 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 に表示されるログメッセージを作成できます。すべての Android ログメッセージには、タグと優先度が関連付けられます。システムのログメッセージのタグは、メッセージの発信元であるシステム コンポーネントを示す短い文字列です。

以下に、使用するログメソッドを優先度の高い順に示します。

ユーザー定義タグでは、役に立つと思われる任意の文字列(現在のクラスの名前など)を指定できます。このタグは、次のように、Log メソッド呼び出しで定義します。

Kotlin

Log.d(tag, message)

Java

Log.d(tag, message);

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

詳細ログは、開発時以外はアプリにコンパイルしないでください。デバッグログはコンパイルされますが、実行時に除去されます。エラーログ、警告ログ、情報ログは常に保持されます。

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

クラス内で 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);

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

logcat メッセージの形式

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

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

PID は「プロセス識別子」、TID は「スレッド識別子」を表します。スレッドが 1 つしかない場合、これらは同じになることがあります。

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

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

ログレベルを設定する

ログレベルを設定すると、logcat ですべてのメッセージを表示するか、最も重大な状態を示すメッセージのみを表示するかを制御できます。

ログレベルの設定にかかわらず、logcat はすべてのメッセージを収集します。ログレベルの設定は、logcat に表示される内容を制御するだけです。

[Log level] メニューで、次のいずれかの値を選択します。

  • Verbose: すべてのログメッセージを表示します(デフォルト)。
  • Debug: 開発時にのみ役立つデバッグログ メッセージと、このリストのこれより下のレベルのメッセージを表示します。
  • Info: 通常の使用時に発生するログメッセージと、このリストのこれより下のレベルのメッセージを表示します。
  • Warn: エラーほど重大でない潜在的な問題と、このリストのこれより下のレベルのメッセージを表示します。
  • Error: エラーの原因となった問題と、このリストのこれより下のレベルのメッセージを表示します。
  • Assert: デベロッパーが絶対に発生してはならないと考える問題を表示します。

logcat メッセージを検索する

現在 logcat に表示されているメッセージを検索する手順は次のとおりです。

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

    入力に応じて logcat 出力の表示が変化します。

  3. Enter キーを押すと、現在のセッション中、検索文字列がメニューに保存されます。
  4. 検索メニューでその文字列を選択すると、繰り返し検索できます。必要に応じて、[Regex] を選択または選択解除します。

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

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

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

フィルタを定義して適用する手順は次のとおりです。

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

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

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

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

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

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

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

ガベージ コレクション(GC)イベントが発生して、情報が logcat に出力される場合があります。

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

Dalvik ログメッセージ

Dalvik では、ART と異なり、すべての GC で次の情報が logcat に出力されます。

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

ログメッセージが蓄積されているときは、ヒープ統計情報の増加に注意してください。この値が上昇し続ける場合は、メモリリークが発生している可能性があります。

Dalvik のログメッセージには、以下の語句が含まれます。

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

ART ログメッセージ

ART では、Dalvik と異なり、明示的にリクエストされなかった GC のログメッセージは記録されません。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

ART のログメッセージには、以下の語句が含まれます。

GC_Reason
GC がトリガーされた理由とコレクションの種類。次のような理由が表示されます。
Concurrent
アプリのスレッドを中断しないコンカレント GC。この GC は、バックグラウンド スレッドで実行され、割り当てを妨げません。
Alloc
GC が開始された理由は、ヒープに空きがない状態でアプリがメモリを割り当てようとしたことです。この場合、ガベージ コレクションは割り当てスレッドで発生します。
Explicit
アプリによって(System.gc() または Runtime.gc() の呼び出しなどで)明示的にリクエストされた GC。 なお、ART でも Dalvik と同様に、GC が実行されることを信じて、明示的な GC のリクエストは可能な限り避けることをおすすめします。明示的な GC は、割り当てスレッドをブロックして不必要に CPU サイクルを浪費するため、避けるべきです。また、明示的な GC によって他のスレッドがプリエンプトされると、ジャンク(アプリのスタッタリング、激しい震動、停止など)が発生することがあります。
NativeAlloc
ネイティブ割り当て(ビットマップや RenderScript 割り当てオブジェクトなど)によるネイティブ メモリ負荷が原因で発生した GC。
CollectorTransition
ヒープ遷移によって発生した GC。これは、実行時の GC 戦略の変化(アプリが一時停止を検知できる状態が切り替わったときなど)が原因で発生します。コレクター遷移では、フリーリストで管理されたスペースからバンプポインタ スペース(またはその逆)にすべてのオブジェクトがコピーされます。

これは、8.0 より前のバージョンの Android を搭載した低 RAM デバイスで、アプリのプロセス状態が一時停止を検知できる状態から一時停止を検知できない状態に(またはその逆に)切り替わった場合にのみ発生します。一時停止を検知できる状態とは、たとえばアプリがフォアグラウンドで動作している(ユーザーが GC の一時停止を検知できる)ときの状態です。

HomogeneousSpaceCompact
同種スペース コンパクションとは、フリーリスト スペースからフリーリスト スペースへの圧縮です。これは、一般的に、アプリが一時停止を検知できないプロセス状態に移行したときに発生します。この処理は、主として RAM 使用量を削減し、ヒープをデフラグするために行われます。
DisableMovingGc
これは GC の発生理由ではなく、コンカレント ヒープ コンパクションの実行中に GetPrimitiveArrayCritical の使用が原因でコレクションがブロックされことの通知です。一般的に、GetPrimitiveArrayCritical は Moving コレクターを制限するため、使用しないことを強くおすすめします。
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
このガベージ コレクションによってラージ オブジェクト スペースから回収されたオブジェクトの数。
Large_object_size_freed
このガベージ コレクションによってラージ オブジェクト スペースから回収されたバイトの数。
Heap_stats
空き領域の割合、および(ライブ オブジェクト数)/(総ヒープサイズ)。
Pause_time(s)
一般的に、一時停止時間は、GC の実行中に変更されたオブジェクト参照の数に比例します。現在、ART CMS GC は GC の終了間際に一度だけ一時停止します。 Moving GC は一時停止時間が長く、GC 期間の大半に及びます。

logcat に大量の GC メッセージが見受けられる場合は、ヒープ統計情報が増加していないかを確認してください。この値が上昇し続けていて減少が見られない場合は、メモリリークが発生している可能性があります。

また、理由が「Alloc」の GC が見受けられる場合は、ヒープ容量が上限に近づいており、近い将来にメモリ不足例外が発生すると予想されます。