Android: java.lang.OutOfMemoryError: не удалось выделить выделение байтов 23970828 с 2097152 бесплатными байтами и 2 МБ до тех пор, пока OOM

Я хочу показать Растровое изображение в ImageView с SD-карты, которая уже сохранена. После запуска моего приложения происходит сбой и получение OutOfMemoryError ошибки:

(java.lang.OutOfMemoryError: не удалось выделить выделение байтов 23970828 с 2097152 бесплатными байтами и 2 МБ до 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)

Ответ 1

OutOfMemoryError - самая распространенная проблема, возникающая в Android, особенно при работе с растровыми изображениями. Эта ошибка генерируется виртуальной машиной Java (JVM), когда объект не может быть выделен из-за нехватки памяти, а также сборщик мусора не может освободить некоторое пространство.

Как уже упоминалось Алексеем, вы можете добавить ниже сущности в ваш файл манифеста 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, особенно здесь: Эффективное отображение растровых изображений

Прочитайте все 5 тем и перепишите свой код еще раз. Если он все еще не работает, мы будем рады видеть, что вы сделали неправильно с учебным материалом.

Вот некоторые из возможных ответов для этих типов ошибок в SOF

Android: BitmapFactory.decodeStream() из памяти с файлом 400 КБ с бесплатной кучей в 2 МБ

Как решить проблему java.lang.OutOfMemoryError в Android

Android: java.lang.OutOfMemoryError

java.lang.OutOfMemoryError

Решение для OutOfMemoryError: размер растрового изображения превышает бюджет VM

Изменить: из комментариев @cjnash

Для тех, у кого все еще были сбои после добавления этой строки, попробуйте прикрепить изображение к папке res/drawable-xhdpi/вместо res/drawable/, и это может решить вашу проблему.

Ответ 2

Вы пытались добавить это в свой манифест в приложениях? 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" >

Ответ 3

На самом деле вы можете добавить в свой манифест следующие строки 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">

Ответ 4

Для меня проблема заключалась в том, что мой .png файл был декомпрессирован, чтобы быть действительно огромным растровым изображением в памяти, потому что изображение имеет очень большие размеры (хотя размер файла был крошечным).

Итак, исправление было просто изменить размер изображения:)

Ответ 5

Это должно работать

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

 mBitmapSampled = BitmapFactory.decodeFile(mCurrentPhotoPath,options);

Ответ 6

Изменить размер вашего изображения перед настройкой на ImageView следующим образом:

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

где размер - фактический размер ImageView. Вы можете достичь размера, измеряя:

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

и используйте следующий размер imageView.getMeasuredWidth() и imageView.getMeasuredHeight() для scaling.

Ответ 7

Используйте Glide Library и измените размер на меньший размер;

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

Ответ 8

Я решил эту проблему, изменив размер изображения до меньшего размера. Я использую форму xamarin. уменьшение размера изображения PNG разрешило проблему.

Ответ 9

Я получил ошибку ниже

"E/art: Throwing OutOfMemoryError" Не удалось выделить байт 47251468 выделение с 16777120 бесплатных байтов и 23 МБ до OOM "

после добавления android:largeHeap="true" в AndroidManifest.xml, тогда я избавился от всех ошибок

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

Ответ 10

Soluton попробуйте это в вашем файле манифеста и используйте Glide Library

compile '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);
        } 

Android: hardwareAccelerated = "ложь"

Android: largeHeap = "истинный"

<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();
    }
}

Ответ 11

Проблема: не удалось выделить выделение байтов 37748748 с помощью 16777120 свободные байты и 17MB до OOM

Решение: 1. открыть файл манифеста 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">

Ответ 12

У меня тоже была проблема.

То же самое с большинством других выше. Проблема вызвана огромным изображением.

Просто измените размер некоторых изображений, и не нужно менять какой-либо код.

Ответ 13

Я обнаружил, что изображения в папке "drawable" будут преобразованы в гораздо большее изображение на телефонах с высоким разрешением. Например, образ 200 тыс. Будет повторно отображен до более высокого разрешения, например 800k или 32000k. Я должен был открыть это самостоятельно и на сегодняшний день не видел документацию для этой ловушки памяти кучи. Чтобы предотвратить это, я помещаю все в папку drawable-nodpi (в дополнение к использованию "опций" в BitmapFactory на основе конкретной кучи устройства). Я не могу позволить себе, чтобы размер моего приложения раздувался с несколькими доступными папками, особенно, поскольку диапазон экранных настроек настолько велик. Трудность в том, что студия сейчас конкретно не указывает папку "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.

введите описание изображения здесь

Обязательно зайдите в папку nodpi в диалоговом окне, так как в представлении проекта не будут отображаться все доступные папки, как это было раньше, поэтому не будет сразу видно, что это было неправильно. Студия воссоздала ванильный "drawable" в какой-то момент для меня после того, как я удалил его давно:

введите описание изображения здесь

Ответ 14

Я новичок в разработке 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();

Ответ 15

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, поэтому это предотвратит проблему с памятью.

Ответ 16

В некоторых случаях (например, операции в цикле) сборщик мусора медленнее, чем ваш код. Вы можете использовать вспомогательный метод от этого ответа до дожидаться сборщика мусора.

Ответ 17

Я столкнулся с этой проблемой, когда я не убил свою прежнюю деятельность, перейдя к новому действию. Я установил его с помощью finish();

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

Ответ 18

Это сработало для меня: просто перемещайте изображения из выпадающей папки в drawable-hdpi.

Ответ 19

Вы должны изменить размер объекта в drawable. Он слишком большой для Android. Например, если вы задаете изображение с изображением с меньшим количеством пикселей. Меня устраивает. Благодарю. :)

Ответ 20

Ваше приложение разбивается, потому что ваш размер изображения (в MB или КБ) слишком велик, поэтому он не выделяет пространство для этого. Поэтому, прежде чем вставлять изображение в растягиваемое, просто уменьшите размер.

ИЛИ ЖЕ

Вы можете добавить следующее в тег приложения в Manifest.xml

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

После добавления этого приложения не произойдет сбой.

  • всегда используйте изображения меньшего размера в приложении.
  • Если вы добавляете большие размеры изображений в приложение, вы должны добавить выше syntex, но размер приложения будет увеличиваться.

Ответ 21

Моя проблема решена после добавления

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

в файле Build.Gradle

Ответ 22

При загрузке изображения попробуйте уменьшить качество изображения, которое является вторым параметром Bitmap. Это было решение в моем случае. Раньше было 90, затем я попытался с 60 (как сейчас в коде ниже).

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

Ответ 23

Попробуйте простейший. Возможно, ваше приложение рушится, потому что ваш размер изображения (в МБ) слишком велик, поэтому он не выделяет пространство для этого. Поэтому, прежде чем вставлять изображение в чертеж, просто уменьшите размер с помощью любого программного обеспечения для просмотра или если вы снимаете изображение из галереи во время выполнения, а затем сохраняете его сжатие растрового изображения. Это сработало для меня. определенно для u будет.

Ответ 24

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();

Затем в теге Appliaction добавьте largeheapsize = "true

Ответ 25

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.....

Ответ 26

Используйте библиотеку загрузки изображений, такую как Picasso или Glide. Использование этих библиотек предотвратит сбои в будущем.

Ответ 27

Я полагаю, вы хотите использовать это изображение в качестве значка. Как говорит Android, ваше изображение слишком велико. Вам просто нужно масштабировать изображение, чтобы Android знал, какой размер изображения использовать и когда он соответствует разрешению экрана. Для этого в Android Studio: 1. щелкните правой кнопкой мыши на папке res, 2. выберите Image Asset 3. Выберите значок Type 4. Присвойте значку имя 5. Выберите Image на Asset Type 6. Урежьте ваше изображение Нажмите Next и закончите, В вашем XML или исходном коде просто обратитесь к изображению, которое теперь будет находиться либо в папке макета, либо в папке mipmap в соответствии с выбранным типом ресурса. Ошибка уйдет.