Android: java.ленг.Исключение OutOfMemoryError: не удалось выделить 23970828 выделения байта с 2097152 байт свободного пространства и 2Мб до ООМ


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

(java.ленг.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)
24 230

24 ответа:

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

вы должны определенно прочитайте некоторые из концепций разработчиков андроидов, особенно здесь:Отображение Растровых Изображений Эффективно

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

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

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

как решить java.ленг.OutOfMemoryError беда в Android

Android: java.ленг.OutOfMemoryError

java.ленг.OutOfMemoryError

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

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

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

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

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

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

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

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

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

 mBitmapInsurance = BitmapFactory.decodeFile(mCurrentPhotoPath,options);

изменение размера ваше изображение перед установкой в 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.

использовать Скользить Библиотека и переопределить размер до меньшего размера;

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

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

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

"E/ art: выбрасывание OutOfMemoryError" не удалось выделить 47251468 байт выделение с 16777120 свободных байт и 23 Мб до ООМ"

после добавления android:largeHeap="true" in 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">

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

compile ' com.на GitHub.bumptech.скольжение:скольжение: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= "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">

использовать эту библиотеку

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

проблема: не удалось выделить выделение 37748748 байт с 16777120 свободные байты и 17 Мб до ООМ

решение : 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">

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

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

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

Я новичок в разработке android, но я надеюсь, что мое решение помогает, оно отлично работает на моем состоянии. Im с помощью 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();

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

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

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

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

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 разрешение, так что это предотвратит из-за проблемы с памятью

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

enter image description here

вы должны изменить размер объекта в drawable. Это слишком большой для android, чтобы отобразить. например, если вы устанавливаете изображение, попробуйте изображение с меньшим количеством пикселей. Это работает на меня. Спасибо. :)

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

или

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

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

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

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

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

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

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

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

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

в build.Gradle file

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