ひつじのにっき

mhidakaのにっきです。たまに長文、気が向いたとき更新。

OutOfMemoryErrorを知る


日本Androidの会 関西支部 マニアック勉強会での発表資料です。

発表後に指摘を頂き、該当箇所を修正しています。
ありがとうございます。

  • JNIオブジェクトにはGCが効くよ、という点

(nativeでのmallocには効かないです)。今回のポイントはBitmap.recycle()です。


BitmapFactory利用時に、大きな画像を読み込むとOutOfMemoryErrorが発生するケースがあります。
OOMを避けるための方法を紹介しました。

ポイントは以下の3点です。

Bitmap.recycle() Bitmap.isRecycle()を活用

recycleメソッドを呼び出しておくと、メモリが足りなくなった段階で自動的に
メモリを解放してくれます。描画完了後、次回描画まで間がある場合などに使えます。
もちろん次にBitmapを使う際は再デコードが必要になりますが、OOMに陥るのを避けることが出来ます
(isRecycleメソッドでメモリ解放済か、まだ確保されているのかがboolで分かります)。

//利用終了後
bitmap.recycle();

//次使うときのチェック
if(bitmap.isRecycle()){
    //再読込処理
    bitmap = BitmapFactory.decodeFile(...);
}

Android Developers Bitmap.recycle()
http://developer.android.com/intl/ja/reference/android/graphics/Bitmap.html#recycle%28%29

BitmapFactory.Options.inPurgeable

Android SDK1.6で追加されました。
BitmapFactory.decodeFileや、decodeResourceで指定できます。
効果はBitmap.recycleと同様にシステムがメモリ不足に陥った際に解放されます。

Bitmap.Config に ARGB_8888をやめてRGB_565/ARGB_4444を指定

ARGB8888を指定するとαとRGB8ビットで32ビット階調で画像を扱います。1画素あたり4バイト消費します。
単純な表示のみならRGB_565を利用すると半分の2バイトの消費で済みます。
また、アルファブレンディングなどの用途だとARGB_4444指定でこちらも、半分の2バイトです。