web-dev-qa-db-ja.com

Android:Java.lang.OutOfMemoryError:2097152の空きバイトと2MBの23970828バイトをOOMまで割り当てられませんでした

ImageView に保存されている Bitmap imageを表示したい実行後、アプリケーションがクラッシュして OutOfMemoryError のエラーが発生

(Java.lang.OutOfMemoryError:2097152の空きバイトと2OMMBで、23970828バイトの割り当てをOOMに失敗しました)

私にはわからないし、なぜそれがメモリ不足になったのか。私は自分の画像サイズが非常に大きいと思うのでそれを変更しようとしました。

Iterator<String> it = imageArray.iterator();
while (it.hasNext()) {
  Object element = it.next();
  String objElement = element.toString();
  Log.e("objElement ", " = " + objElement);
  final ImageView imageView = new ImageView (getContext());
  final ProgressBar pBar = new ProgressBar(getContext(), null, 
                                           Android.R.attr.progressBarStyleSmall);
  imageView.setTag(it);
  pBar.setTag(it);

  imageView.setImageResource(R.drawable.img_placeholder);
  pBar.setVisibility(View.VISIBLE);

  if (objElement.endsWith(mp3_Pattern)) {
     Log.e("Mp3 ", " ends with ");
     pBar.setVisibility(View.GONE);
     imageView.setImageResource(R.drawable.audio_control);
  }
  if (objElement.endsWith(png_Pattern)) {
     Bitmap bitmap = BitmapFactory.decodeFile(objElement);
     int size = Math.min(bitmap.getWidth(), bitmap.getHeight());
     int x = (bitmap.getWidth() - size) / 2;
     int y = (bitmap.getHeight() - size) / 2;
     Bitmap bitmap_Resul = Bitmap.createBitmap(bitmap, x, y, size, size);
     Log.e("bitmap_Resul "," = "+ bitmap_Resul);

     if (bitmap_Resul != bitmap) {
        bitmap.recycle();
     }
     imageView.setImageBitmap(bitmap_Resul);
     Log.e("png_Pattern ", " ends with ");
     Log.e(" bitmap "," = " + bitmap);
  }

  holder.linearLayout.addView(imageView);
  holder.linearLayout.addView(pBar);

ログ猫情報:

08-27 14:11:15.307    1857-1857/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.tazeen.classnkk, PID: 1857
    Java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM
            at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
            at Android.graphics.Bitmap.nativeCreate(Native Method)
            at Android.graphics.Bitmap.createBitmap(Bitmap.Java:812)
            at Android.graphics.Bitmap.createBitmap(Bitmap.Java:789)
            at Android.graphics.Bitmap.createBitmap(Bitmap.Java:709)
            at Android.graphics.Bitmap.createBitmap(Bitmap.Java:634)
            at com.example.tazeen.classnkk.AllPosts_Page$MyListAdapter.getView(AllPosts_Page.Java:357)
            at Android.widget.AbsListView.obtainView(AbsListView.Java:2347)
            at Android.widget.ListView.makeAndAddView(ListView.Java:1864)
            at Android.widget.ListView.fillDown(ListView.Java:698)
            at Android.widget.ListView.fillFromTop(ListView.Java:759)
            at Android.widget.ListView.layoutChildren(ListView.Java:1659)
            at Android.widget.AbsListView.onLayout(AbsListView.Java:2151)
            at Android.view.View.layout(View.Java:15671)
            at Android.view.ViewGroup.layout(ViewGroup.Java:5038)
            at Android.widget.LinearLayout.setChildFrame(LinearLayout.Java:1703)
            at Android.widget.LinearLayout.layoutVertical(LinearLayout.Java:1557)
            at Android.widget.LinearLayout.onLayout(LinearLayout.Java:1466)
            at Android.view.View.layout(View.Java:15671)
            at Android.view.ViewGroup.layout(ViewGroup.Java:5038)
            at Android.widget.FrameLayout.layoutChildren(FrameLayout.Java:579)
            at Android.widget.FrameLayout.onLayout(FrameLayout.Java:514)
            at Android.view.View.layout(View.Java:15671)
            at Android.view.ViewGroup.layout(ViewGroup.Java:5038)
            at Android.widget.LinearLayout.setChildFrame(LinearLayout.Java:1703)
            at Android.widget.LinearLayout.layoutVertical(LinearLayout.Java:1557)
            at Android.widget.LinearLayout.onLayout(LinearLayout.Java:1466)
            at Android.view.View.layout(View.Java:15671)
            at Android.view.ViewGroup.layout(ViewGroup.Java:5038)
            at Android.widget.FrameLayout.layoutChildren(FrameLayout.Java:579)
            at Android.widget.FrameLayout.onLayout(FrameLayout.Java:514)
            at Android.view.View.layout(View.Java:15671)
            at Android.view.ViewGroup.layout(ViewGroup.Java:5038)
            at Android.view.ViewRootImpl.performLayout(ViewRootImpl.Java:2086)
            at Android.view.ViewRootImpl.performTraversals(ViewRootImpl.Java:1843)
            at Android.view.ViewRootImpl.doTraversal(ViewRootImpl.Java:1061)
            at Android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.Java:5885)
            at Android.view.Choreographer$CallbackRecord.run(Choreographer.Java:767)
            at Android.view.Choreographer.doCallbacks(Choreographer.Java:580)
            at Android.view.Choreographer.doFrame(Choreographer.Java:550)
            at Android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.Java:753)
            at Android.os.Handler.handleCallback(Handler.Java:739)
            at Android.os.Handler.dispatchMessage(Handler.Java:95)
            at Android.os.Looper.loop(Looper.Java:135)
            at Android.app.ActivityThread.main(ActivityThread.Java:5257)
            at Java.lang.reflect.Method.invoke(Native Method)
            at Java.lang.reflect.Method.invoke(Method.Java:372)
            at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:903)
            at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:698)
278
androidTag

OutOfMemoryError は、特にビットマップを処理している間にAndroidで発生する最も一般的な問題です。このエラーは、メモリスペースの不足のためにオブジェクトを割り当てることができず、ガベージコレクタがスペースを解放できないときに、Java仮想マシン(JVM)によってスローされます。

Alekseyが述べたように、マニフェストファイルAndroid:hardwareAccelerated="false"Android:largeHeap="true"に以下のエンティティを追加することができます。

<application
    Android:allowBackup="true"
    Android:hardwareAccelerated="false"
    Android:icon="@mipmap/ic_launcher"
    Android:label="@string/app_name"
    Android:largeHeap="true"
    Android:supportsRtl="true"
    Android:theme="@style/AppTheme">

あなたは間違いなくここで特にここにAndroids Developerの概念のいくつかを読むべきです: ビットマップを効率的に表示する

5つすべてのトピックを読み、コードをもう一度書き直してください。それでもうまくいかない場合は、チュートリアルの資料で間違ったことをしたことを確認してください。

ここでいくつかのSOFのエラーのタイプに対する可能な答え

Android:BitmapFactory.decodeStream()2MBの空きヒープを持つ400KBファイルでメモリ不足

AndroidのJava.lang.OutOfMemoryError問題を解決する方法

アンドロイド:Java.lang.OutOfMemoryError

Java.lang.OutOfMemoryError

OutOfMemoryErrorの解決策:ビットマップのサイズがVM budgetを超える

編集:@ cjnashのコメントから

この行を追加してもまだクラッシュしている人は、res/drawable /ではなくres/drawable-xhdpi /フォルダにイメージを貼り付けてみてください。これで問題が解決する可能性があります。

422
King of Masses

これをアプリケーションのマニフェストに追加してみましたか? Android:largeHeap="true"

このような

  <application
      Android:name=".ParaseApplication"
      Android:allowBackup="true"
      Android:icon="@mipmap/ic_launcher"
      Android:label="@string/app_name"
      Android:theme="@style/AppTheme"
      Android:largeHeap="true" >
76
TSG

実際には、マニフェストに次の行を追加することができます。Android:hardwareAccelerated="false"Android:largeHeap="true"これは状況によっては機能していますが、コードの他の部分ではこれについて議論できることに注意してください。

<application
    Android:allowBackup="true"
    Android:hardwareAccelerated="false"
    Android:icon="@mipmap/ic_launcher"
    Android:label="@string/app_name"
    Android:largeHeap="true"
    Android:supportsRtl="true"
    Android:theme="@style/AppTheme">
25

私にとっては、イメージのサイズが非常に大きいため(ファイルサイズが小さい場合でも)、.pngファイルがメモリ内で非常に大きなビットマップになるように解凍されていました。

だから修正は単に画像のサイズを変更することでした:)

19

これはうまくいくはずです

 BitmapFactory.Options options = new BitmapFactory.Options();
 options.inSampleSize = 8;

 mBitmapSampled = BitmapFactory.decodeFile(mCurrentPhotoPath,options);
18
Akshay komarla

グライドライブラリを使用 およびサイズを小さいサイズに変更します。

Glide.with(mContext).load(imgID).asBitmap().override(1080, 600).into(mImageView);
8
Mahdi Azadbar

サイズ変更 このようにImageViewに設定する前に/ /あなたの画像:

Bitmap.createScaledBitmap(_yourImageBitmap, _size, _size, false);

サイズはImageViewの実際のサイズです。あなたは測定することによってサイズに達することができます:

imageView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));

scalingには次のサイズのimageView.getMeasuredWidth()imageView.getMeasuredHeight()を使います。

8

画像のサイズを小さくすることでこの問題を解決しました。私はxamarin形式を使っています。 PNG画像のサイズを小さくすると問題は解決しました。

4
maxspan

エラー以下になりました

"E/art:Throwing OutOfMemoryError" 16777120の空きバイトと23MBの47251468バイトの割り当てをOOMまで割り当てられませんでした。

AndroidManifest.xmlにAndroid:largeHeap="true"を追加した後 それから私はすべてのエラーを取り除きます

<application
    Android:allowBackup="true"
    Android:icon="@mipmap/guruji"
    Android:label="@string/app_name"
    Android:supportsRtl="true"
    Android:largeHeap="true"
    Android:theme="@style/AppTheme">
3
saigopi

問題:OOMまで、37778748バイトの割り当てを16777120の空きバイトと17MBに割り当てられませんでした

解決策:1.マニフェストファイルを開く2. applicationタグの内側に2行以下を追加する

 Android:hardwareAccelerated="false"
 Android:largeHeap="true"

例:

 <application
        Android:allowBackup="true"
        Android:hardwareAccelerated="false"
        Android:largeHeap="true"
        Android:icon="@mipmap/ic_launcher"
        Android:label="@string/app_name"
        Android:roundIcon="@mipmap/ic_launcher_round"
        Android:supportsRtl="true"
        Android:theme="@style/AppTheme">
3
Kishore Reddy

Solutonはあなたのマニフェストファイルでこれを試してGlide Libraryを使う

'com.github.bumptech.glide:glide:3.7.0'をコンパイルしてください。

    **Use Glide Library and Override size to less size;**

 if (!TextUtils.isEmpty(message.getPicture())) {
            Glide.with(mContext).load(message.getPicture())
                    .thumbnail(0.5f)
                    .crossFade()
                    .transform(new CircleTransform(mContext))
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    .into(holder.imgProfile);
        } 

アンドロイド:hardwareAccelerated = "false"

アンドロイド:largeHeap = "true"

<application
    Android:allowBackup="true"
    Android:hardwareAccelerated="false"
    Android:icon="@mipmap/ic_launcher"
    Android:label="@string/app_name"
    Android:largeHeap="true"
    Android:supportsRtl="true"
    Android:theme="@style/AppTheme">

このライブラリを使う

  compile 'com.github.bumptech.glide:glide:3.7.0'   

その働きハッピーコーディング

import Android.content.Context;
import Android.graphics.Bitmap;
import Android.graphics.BitmapShader;
import Android.graphics.Canvas;
import Android.graphics.Paint;

import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;


public class CircleTransform extends BitmapTransformation {
    public CircleTransform(Context context) {
        super(context);
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return circleCrop(pool, toTransform);
    }

    private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
        if (source == null) return null;

        int size = Math.min(source.getWidth(), source.getHeight());
        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;

        // TODO this could be acquired from the pool too
        Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);

        Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        Paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        Paint.setAntiAlias(true);
        float r = size / 2f;
        canvas.drawCircle(r, r, r, Paint);
        return result;
    }

    @Override
    public String getId() {
        return getClass().getName();
    }
}
3
Keshav Gera

私も問題がありました。

上記の他のほとんどのものと同じです。問題は巨大な画像が原因です。

画像のサイズを変更するだけで、コードを変更する必要はありません。

2
Mike Yan

私は、 'drawable'フォルダ内の画像が、ハイビジョン電話ではもっと大きな画像に変換されることを発見しました。例えば、200kの画像は、800kや32000kのように高い解像度にリサンプリングされます。私は自分でこれを発見しなければならず、これまでこのヒープメモリトラップのドキュメントを見たことがありませんでした。これを防ぐために、(特定のデバイスヒープに基づいてBitmapFactoryで 'options'を使用することに加えて)すべてをdrawable-nodpiフォルダーに入れました。私は自分のアプリのサイズを複数の描画可能なフォルダで肥大化させることはできません。特に、画面定義の範囲が非常に広くなったためです。難しいのは、スタジオがプロジェクトビューで 'drawable-nodpi'フォルダを明示していないことです。単に 'drawable'フォルダを表示しているだけです。注意しないと、スタジオのこのフォルダに画像をドロップしても、実際にはdrawable-nodpiにドロップされません。

Careful here 'backgroundtest' did not actually go to drawable-nodpi and will 
be resampled higher, such as 4x or 16x of the original dimensions for high def screens.

enter image description here

プロジェクトビューでは、すべての描画可能なフォルダが別々に表示されるわけではないので、ダイアログ内のnodpiフォルダまで必ずクリックしてください。そのため、間違ったフォルダに移動したことはすぐにはわかりません。ずっと前に削除していたStudioが、ある時点でVanillaの「drawable」を再作成しました。

enter image description here

2
Androidcoder

私はAndroid開発の初心者ですが、私の解決策が役立つことを願っています、それは私の状態で完全に動作します。 Imageviewを使用していて、背景を "src"に設定しています。フレームアニメーションを作成しようとしているからです。私は同じエラーを得たが、私はこれをコーディングしようとしたときそれは働いた

int ImageID = this.Resources.GetIdentifier(questionPlay[index].Image.ToLower(), "anim", PackageName);
            imgView.SetImageResource(ImageID);
            AnimationDrawable animation = (AnimationDrawable)imgView.Drawable;
            animation.Start();
            animation.Dispose();
1
DianeFlores
Bitmap image =((BitmapDrawable)imageView1.getDrawable()).getBitmap();

ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();

image.compress(Bitmap.CompressFormat.JPEG,50/100,byteArrayOutputStream);

50/100 100を使用すると、元の解像度でアプリがメモリ不足のため停止することがあります。

50以下または100以下の場合、これは50%以下または100以下の解像度になるため、メモリ不足の問題を回避できます。

1
RAHINUR RAHMAN

追加後に問題が解決しました

 dexOptions {
        incremental true
        javaMaxHeapSize "4g"
        preDexLibraries true
        dexInProcess = true
    }

build.Gradleファイル内

1
Midhilaj

これは私のために働きました:ただdrawableフォルダからdrawable-hdpiにイメージを動かしてください。

1
Hossein Amini

私はこの問題に遭遇したのですが、新しい活動に移ったときに古い活動を中断しなかったのです。 finish();で修正しました

    Intent goToMain = new Intent(this,MainActivity.class);
    startActivity(goToMain);
    finish();
1
Jason Hu

あなたはdrawableでオブジェクトのサイズを変える必要があります。 Androidが表示するには大きすぎます。例えばあなたがimageを設定しているならば、より少ないピクセルでimageを試してください。わたしにはできる。ありがとう。 :)

1

場合によっては(例えば、ループ内の操作)ガベージコレクタの方が遅いあなたのコードよりも_。この答えから helperメソッドを使うことができます to ガベージコレクタを待つ

1
Zon

画像サイズ(MBまたはKB)大きすぎるのため、アプリはクラッシュしています。そのため、領域は割り当てられていません。そのため、画像をドロウアブルに貼り付ける前に、サイズを小さくするだけです。

OR

Manifest.xmlのapplicationタグにフォローを追加できます。

 Android:hardwareAccelerated="false"
    Android:largeHeap="true"
    Android:allowBackup="true"

このアプリを追加した後にクラッシュしません。

  • appでは常にサイズの小さい画像を使用します。
  • アプリに大きなサイズの画像を追加する場合は、上記のsyntexを追加する必要がありますが、アプリのサイズは大きくなります。
1
rhaldar

これをアプリケーションのマニフェストに追加しますか? Android:largeHeap = "true"

1
SAURABH OMER

Picasso または Glide のような画像ロードライブラリを使用してください。これらのライブラリを使用すると、将来のクラッシュを防ぐことができます。

0
stream = activity.getContentResolver().openInputStream(uri);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;

bitmap = BitmapFactory.decodeStream(stream, null, options);
int Height = bitmap.getHeight();
int Width = bitmap.getWidth();
enter code here
int newHeight = 1000;
float scaleFactor = ((float) newHeight) / Height;
float newWidth = Width * scaleFactor;

float scaleWidth = scaleFactor;
float scaleHeight = scaleFactor;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
resizedBitmap= Bitmap.createBitmap(bitmap, 0, 0,Width, Height, matrix, true);
bitmap.recycle();

次に、アプリケーションタグに大きなヒープサイズを追加します= "true

0

画像をアップロードする場合は、ビットマップの2番目のパラメータである画質を下げてみてください。これが私の場合の解決策でした。以前は90でしたが、次に60で試しました(以下のコードにあります)。

Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
finalBitmap.compress(Bitmap.CompressFormat.JPEG,60,baos);
byte[] b = baos.toByteArray();
0
Teo Mihaila

この画像をアイコンとして使いたいと思います。 Androidがあなたに言っているように、あなたのイメージは大きすぎます。あなたがしなければならないのは、Androidがどのサイズの画像を使用するのか、また画面の解像度に応じていつ認識できるように、画像を拡大縮小することです。これを行うには、Android Studioで次の操作を行います。1. resフォルダーを右クリックします。2. Image Assetを選択します。3.アイコンタイプを選択します。4.アイコンに名前を付けます5.アセットタイプでImageを選択します。 xmlまたはソースコードで、選択したアセットの種類に応じて、レイアウトフォルダまたはミップマップフォルダに配置される画像を参照してください。エラーは消えます。

最も簡単なものを試してください。多分あなたのアプリはクラッシュしていますあなたのイメージサイズ(MB)は大きすぎてそれはそれのためのスペースを割り当てていません。そのため、画像をドロウアブルに貼り付ける前に、任意のビューアソフトウェアでサイズを縮小するか、実行時にギャラリーから画像を取得する場合は、保存する前にビットマップを圧縮してください。それは私のために働きました。あなたのために間違いなくなります。

0
neens
Last but not the least....

Try Method One:

Simple Add these lines of code in the gradle file

dexOptions {
        incremental true
        javaMaxHeapSize "4g"
     }

Example:

Android {
    compileSdkVersion XX
    buildToolsVersion "28.X.X"

    defaultConfig {
        applicationId "com.example.xxxxx"
        minSdkVersion 14
        targetSdkVersion 19
    }

dexOptions {
        incremental true
        javaMaxHeapSize "4g"
     }
}

*******************************************************************

Method Two:

Add these two lines of code in manifest file...

Android:hardwareAccelerated="false" 
Android:largeHeap="true"

Example:

<application
        Android:allowBackup="true"
        Android:icon="@drawable/ic_launcher"
        Android:hardwareAccelerated="false"
        Android:largeHeap="true"
        Android:label="@string/app_name"
        Android:theme="@style/AppTheme" >
        <activity
            Android:name=".MainActivity"
            Android:label="@string/app_name" >
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />

                <category Android:name="Android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

It will Work for sure any of these cases.....