128
126

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Android】OutOfMemoryと戦う【OOM】

Last updated at Posted at 2014-04-04

\ OutOfMemoryが出たぞー! /

どうする?

1.  画像の息の根を止める
2.  メンバー変数は全て息の根を止める
3.  それでもダメならLargeHeap

基本的には1と2までで大丈夫だと思います。
LargeHeapまで行く場合は、絶対的に画像などの読み込み量が多い時ぐらいにした方が良いと思います。

##1. 画像の息の根を止める

  • Bitmapを使う場合

    Bitmap bitmap;

    private void releaseBitmap() {
        if (bitmap != null) {
            bitmap.recycle();
            bitmap = null;
        }
    }

  • ImageView(ImageButton含む)を扱う場合

    ImageView imageView;

    private void releaseImageView(){
        if(imageView != null){
            // src に画像を設定した場合はこっち
            imageView.setImageDrawable(null);
            // background に画像を設定した場合はこっち
            imageView.setBackgroundDrawable(null);
        }
    }

ImageButtonも同様にやっておきましょう。
忘れがちな事は、backgroundに設定している画像をsetImageDrawable(null) では潰せないことです。
どうせ解放するので、常に両方やっちゃっても構わないと思います。

(ちなみに、Fragment の場合、タイミングは onDetach() でやることをオススメします。以前、onViewDestroyed() でやったら、popBackStack 時のアニメーション前に解放されておかしな挙動になりました。)

##2. メンバー変数は全て息の根を止める

それでも何か漏れていたら、とにかくreleaseしてnullで潰していきましょう。

classによって解放の仕方は異なるので、乱暴にnull埋めするだけだとNGの場合があるので気をつけて下さい。

例えば ListView の場合は

    ListView listView;
    ArrayAdapter<String> arrayAdapter;

    private void releaseView() {
        if (listView != null) {
            listView.setAdapter(null);
            listView = null;
        }

        if (arrayAdapter != null) {
            arrayAdapter.clear();
            arrayAdapter = null;
        }
    }

こんな感じ。
画像を使ったListViewとかだと、漏れるとシャレにならない場合があります。

##3.それでもダメならLargeHeap

4系以降のみです(kacchan6@githubさん、ご指摘ありがとうございます。)

どうしても画像が多くて、setContentView()でlayout読み込む時点でOutOfMemory を吐いてしまう様なレベルの場合は、これでヒープの使用量を増やしてしまうのも手でしょう。
ただし、機種によっては増えないシロモノもいるようなので、最終手段くらいに考えたほうが良いです。

AndroidManifest.xml

    <application
        android:name="jp.ogwork.sample.HogeApplication"
        android:label="@string/app_name"
        android:icon="@drawable/icon"
        android:largeHeap="true" >
    ....

android:largeHeap="true"
を一行添えてあげるだけです。簡単。

以上です。

128
126
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
128
126

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?