メモリリークを解決する

概要

Android で発生しているメモリリーク (Memory Leak) の解決方法です。RecyclerView を使用していて発生するメモリリークを解決した例です。

確認環境

参考情報

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

Inspect your app's memory usage with Memory Profiler

対処方法

ライブラリのバグらしい。

ログイン - Google アカウント

LeakCanary にも丁寧に上記 URL がメッセージに表示され、解決方法として下記の URL が提示されている。

"Fix" for InputMethodManager leaking the last focused view: https://code.google.com/p/android/issues/detail?id=171190 · GitHub

これを元にして試してみたところ、メモリリークはなくなった。下記は Kotlin で書き換えたコード。