[Android][Java] Bitmapによるメモリリークの解決策

 RecyclerViewで大量にImageView、Bitmapを使ってGL error: Out of memory!が出た時にやったこと、解決策を書きます。

 AndroidのBitmapは明示的に解放してあげる必要があるため、Bitmapを大量に・もしくは大きいサイズを使用して解放し忘れるとメモリリークが起きます。

 メモリリークが起きているかは起動終了を繰り返して

adb shell dumpsys meminfo アプリの名前

で使用しているメモリの詳細を見ることでわかります。

※OSのバージョンによってBitmapがどのメモリ領域を使うか違うらしい  → Android公式の説明

解決策1. recycle()


 onDestroyとかでBitmap.recycle()を使用してみる。

if (!bitmap.isRecycled()) {
  bitmap.recycle();
}

解放してもやはりメモリリークが治らない…なぜ

解決策2. Bitmapの参照を切る


 私の場合はこれが原因でした。

 サムネイルやタイトルを保持する情報クラスがサムネイルにBitmapを持っていて、それをImageViewにセットしていました。そしてその情報クラスオブジェクトが生存したままになっていました。

 そのため、recycle()で解放しても参照されているためメモリが解放されないというのが原因だった。

 情報クラスにBitmapを解放、参照を切るするメソッドを作ってあげて、onDestroyなどで呼びます。

class ImageInfo {
    String title;
    Bitmap thumbnail;
    ...

    public void releaseResources() {
        if (!thumbnail.isRecycled()) {
            thumbnail.recycle();
        }        
        thumbnail = null;  // ここで参照を切る!
    }
}

コメントを残す

メールアドレスが公開されることはありません。