概要
Android で発生しているメモリリーク (Memory Leak) の解決方法です。RecyclerView を使用していて発生するメモリリークを解決した例です。
確認環境
- Android Studio 2.1.2
- Compile SDK Version 22
- Build Tools Version 22.0.1
- 実行環境 Sony SOV32 Android 6.0, API 23
参考情報
SQUARE が公開している LeakCanary を使って解析する方法を紹介している。
LeakCanary のサイト。
Android Studio の Memory Monitor の解説。
解析
まずは、LeakCanary を試す。
実機でアプリを起動して、そのまま終了させてみる。すると Dumping memory, app will freeze.
なんてメッセージが出た。
メモリをダンプ中だからアプリがフリーズするよ、ってことかな。
Leaks というアプリがインストールされているので、起動してみると何もない。
Leaks アプリを終了して、再び表示させてみると今度はリーク情報がある。
表示されるまでには時間の経過が必要な様子。
Android Studio の Memory Monitor でも確認してみる。
Initiate GC
を実行した後に、Dump Java Heap
を実行し、次に Analyzer Tasks
を実行することで、Leak Activity は確認できる。
Reference Tree には選択したインスタンスの参照元(どこから参照されているか?)が表示されている。 Depth 0 まで辿っていくと、GC root が下記アイコンで示されている。
下記のようなオブジェクトが GC root になる。
- references on the stack
- Java Native Interface (JNI) native objects and memory
- static variables and functions
- threads and objects that can be referenced
- classes loaded by the bootstrap loader
- finalizers and unfinalized objects
- busy monitor objects
対処方法
ライブラリのバグらしい。
LeakCanary にも丁寧に上記 URL がメッセージに表示され、解決方法として下記の URL が提示されている。
これを元にして試してみたところ、メモリリークはなくなった。下記は Kotlin で書き換えたコード。