はじめに
Androidアプリのメモリリークを検出するライブラリとして、LeakCanaryを利用している方も多いのではないでしょうか。
Android Studioでは、ProfilerからLeakCanaryを利用してメモリリークを解析できるようになりました。
これまでのLeakCanaryと何が異なるのか、Android Studioとの統合によって何ができるようになったのかを、公式情報をもとに整理します。
LeakCanaryとは
LeakCanaryは、Androidアプリで発生したメモリリークを検出するためのライブラリです。
本来破棄されるはずのActivityやFragmentなどが、別のオブジェクトから参照され続けている場合、そのオブジェクトはガベージコレクションの対象になりません。
このような状態が積み重なるとアプリの動作が重くなったり、OutOfMemoryErrorが発生したりする可能性があります。
LeakCanaryを利用するとメモリ上に残っているオブジェクトと、そのオブジェクトが保持されている参照経路を確認できます。
Android Studioへの統合
Android Studio Profilerには、LeakCanaryを利用したメモリリーク解析が専用のタスクとして用意されています。
Profilerから解析を開始しアプリを操作することで、検出されたメモリリークをAndroid Studio上で確認できます。
従来のLeakCanaryでは、主にテスト端末上でヒープ解析が行われていました。
Android Studioとの統合では、解析処理をテスト端末ではなく開発マシン側で実行します。
これにより端末側で解析する場合と比べて、メモリリークの解析を高速化できるとされています。
Android Studio上でできること
Android Studioに統合されたLeakCanaryでは、主に次のことができます。
- Profilerからメモリリークの解析を開始する
- リークしているオブジェクトを確認する
- オブジェクトが保持されている参照経路を確認する
- 解析結果からソースコードの定義元へ移動する
- Geminiを利用して原因の説明や修正案を確認する
それぞれ簡単に見ていきます。
Profilerから解析を開始できる
LeakCanaryによる解析は、Android StudioのProfilerから開始できます。
View
└ Tool Windows
└ Profiler
Profilerで対象のプロセスを選択し、LeakCanaryのタスクを開始します。
アプリを操作してメモリリークが発生すると、その解析結果がAndroid Studio上に表示されます。
LeakCanaryを独立したツールとして扱うのではなく、CPUやメモリの計測と同じProfilerのタスクとして利用できるのが特徴です。
参照経路を確認できる
メモリリークが検出されると、対象のオブジェクトがどのような経路で保持されているのかを確認できます。
例えばシングルトンオブジェクトがActivityを保持している場合、次のような参照関係が考えられます。
SingletonObject
└ activity
└ MainActivity
MainActivityが破棄された後もSingletonObjectから参照されているため、ガベージコレクションの対象になりません。
LeakCanaryの解析結果を見ることで単に「Activityがリークしている」という結果だけでなく、どのオブジェクトから参照され続けているのかを追跡できます。
ソースコードの定義元へ移動できる
Android Studioとの統合による大きなメリットの一つが、解析結果からソースコードへ直接移動できることです。
リークトレースに表示されたクラスやプロパティから、Go to declarationを利用して定義元を開けます。
従来もLeakCanaryの解析結果からクラス名やプロパティ名を確認できましたが、解析結果とソースコードをAndroid Studio内で行き来できるため、原因となっている箇所を調査しやすくなります。
参照関係が複雑なケースほど、この統合の恩恵を受けられそうです。
Geminiに修正を依頼できる
解析結果から、Geminiのエージェントへ修正を依頼することもできます。
Fix with Agentを実行するとリークトレースとプロジェクト内のコードをもとに、メモリリークの原因や修正案が提示されます。
例えば次のような原因を調査する際に役立ちそうです。
- ActivityやFragmentの参照を長期間保持している
- 登録したリスナーを解除していない
- Coroutineが画面のライフサイクルより長く動作している
- コールバックが画面の参照を保持している
- DIコンテナのスコープが適切でない
ただし、メモリリークの修正は単純に参照を削除すればよいとは限りません。
提示された修正内容だけでなく、オブジェクトのライフサイクルや影響範囲も確認したうえで判断する必要があります。
これまでのLeakCanaryとの違い
Android Studioへの統合によってLeakCanaryの検出ロジックそのものが大きく変わったというより、解析から原因調査までの流れがAndroid Studio上にまとめられました。
主な違いを整理すると、次のようになります。
| 項目 | 従来の利用方法 | Android Studioとの統合後 |
|---|---|---|
| 解析処理 | 主にテスト端末上 | 開発マシン上 |
| 解析結果 | 通知や専用画面から確認 | Profiler上で確認 |
| ソースコードの確認 | 対象箇所を自分で探す | 定義元へ直接移動 |
| AIによる支援 | なし | Geminiへ修正を依頼可能 |
特に解析処理を開発マシン側で実行できることと、ソースコードへ直接移動できることが大きな変化です。
LeakCanaryが検出してくれる範囲
LeakCanaryはメモリ上に残っているオブジェクトと参照経路を確認するためのツールです。
解析結果から原因の候補を絞り込めますが、アプリの設計や本来期待されるライフサイクルまですべて判断してくれるわけではありません。
例えばあるオブジェクトが長時間保持されていても、それがアプリの仕様として必要な場合もあります。
そのため、解析結果を確認する際は、次の点を考える必要があります。
- 本来いつ破棄されるべきオブジェクトなのか
- どのオブジェクトが参照を保持しているのか
- その参照は本当に必要なのか
- 参照を解除するタイミングは適切か
Geminiによる支援が追加されても最終的にはオブジェクトのライフサイクルを理解したうえで判断することが重要です。
まとめ
Android StudioではProfilerからLeakCanaryを利用してメモリリークを解析できるようになりました。
解析処理を開発マシン側で行い、検出結果からソースコードの定義元へ直接移動できます。
さらにGeminiへ原因の説明や修正を依頼できるため、メモリリークの検出から原因調査までをAndroid Studio上で進めやすくなっています。
LeakCanaryを導入していてもメモリリークが検出されたときにしか解析結果を見ないという方は多いかもしれません。
Android StudioのProfilerへ統合されたことで、これまでより日常的なデバッグ作業に取り入れやすくなりそうです。
さいごに
東北はとっても涼しくて快適ですね、関東にもこの涼しさをお願いします…笑