java.lang.OutOfMemoryError: Failed to allocate a 840012 byte allocation with 555120 free bytes and 538KB until OOM

マイナーな話にはなっちゃうんですが。
AndroidのMapboxでマーカーを追加していて、タブレットで200個ぐらいマーカーを生成する画面でOOMが起こってクラッシュしてしまう、という不具合に遭遇しました。

ググると大きなBitmapをいっぱい追加するとこれが起きやすいという話です。

https://stackoverflow.com/questions/477572/strange-out-of-memory-issue-while-loading-an-image-to-a-bitmap-object

Android Developersの公式でも紹介されていますね。

https://developer.android.com/topic/performance/graphics

皆さん、大体ファイルを読み込んでアプリに表示する系でこれが発生しているようですね。

私はBitmapの生成を、Mapboxのマーカーをタップした時に出るウィンドウのために作ってまして、下記のような感じになります。

public static Bitmap generate(@NonNull View view) {
int measureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(measureSpec, measureSpec);

int measuredWidth = view.getMeasuredWidth();
int measuredHeight = view.getMeasuredHeight();

view.layout(0, 0, measuredWidth, measuredHeight);
/Bitmap bitmap = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888);

//bitmap.eraseColor(Color.TRANSPARENT);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}

https://docs.mapbox.com/android/maps/examples/symbol-layer-info-window/

コード自体はMapboxの公式サンプルを利用しているだけです。

なので、上述のAndroid DevelopersやStackOverflowにあるような

BitmapFactory.Options

を使ったやり方がどうにもできませんでした…。

なので、

Bitmap bitmap = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888);

Bitmap bitmap = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.RGB_565);

に変更しました。

ARGB_8888 

にすると、1ピクセルにつき、4バイト使うらしいです。


RGB_565

にすると、1ピクセルにつき、2バイト使います。

透明部分とかが表現できませんが、しょうがない…。

ちなみに、手っ取り早くマニフェストファイルに

<application android:largeHeap=”true” > </appplication>

ってして回避することもできるようですが、これは機種によってできなかったりするらしく、また敗北感あるのでやめました…。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です