web-dev-qa-db-fra.com

Android: Java.lang.OutOfMemoryError: échec de l'allocation d'une allocation de 23970828 octets avec 2097152 octets libres et 2 Mo jusqu'au MOO

Je veux montrer le Bitmap image dans ImageView à partir de la carte SD qui est déjà stockée. Après avoir exécuté mon application se bloque et obtient OutOfMemoryError error of:

(Java.lang.OutOfMemoryError: échec de l'allocation d'une allocation de 23970828 octets avec 2097152 octets libres et 2 Mo jusqu'au MOO)

Je n'ai aucune idée ou pourquoi c'est hors de mémoire. Je pense que la taille de mon image est très grande alors j'ai essayé de la changer. 

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

Les informations du chat de journal:

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)
259
androidTag

OutOfMemoryError est le problème le plus courant survenu dans Android alors qu’il s’agissait surtout de bitmaps. Cette erreur est générée par la machine virtuelle Java (JVM) lorsqu'un objet ne peut pas être alloué en raison d'un manque d'espace mémoire et que le garbage collector ne peut pas libérer de l'espace. 

Comme mentionné par Aleksey, vous pouvez ajouter ci-dessous des entités dans votre fichier manifeste Android:hardwareAccelerated="false", Android:largeHeap="true", cela fonctionnera pour certains environnements.

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

vous devriez lire absolument certains concepts d'Androids Developer, spécialement ici: Affichage efficace des images bitmap

Lisez les 5 rubriques et réécrivez votre code. Si cela ne fonctionne toujours pas, nous serons heureux de voir ce que vous avez mal fait avec le didacticiel.

Voici quelques réponses possibles pour ce type d’erreurs dans les fichiers SOF.

Android: BitmapFactory.decodeStream () manque de mémoire avec un fichier de 400 Ko avec un segment de mémoire libre de 2 Mo

Comment résoudre le problème Java.lang.OutOfMemoryError sous Android

Android: Java.lang.OutOfMemoryError

Java.lang.OutOfMemoryError

Solution pour OutOfMemoryError: la taille du bitmap dépasse le budget VM

Edit: D'après les commentaires de @cjnash

Pour tous ceux qui ont encore des plantages après avoir ajouté cette ligne, essayez de coller votre image dans votre dossier res/drawable-xhdpi/au lieu de votre res/drawable/et cela pourrait résoudre votre problème.

397
King of Masses

avez-vous essayé d'ajouter ceci à votre manifeste sous applications? Android:largeHeap="true"?

comme ça

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

En fait, vous pouvez ajouter dans votre manifeste ces lignes Android:hardwareAccelerated="false", Android:largeHeap="true" cela fonctionne dans certaines situations, mais sachez que l’autre partie du code peut être discutée avec cela.

<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

Pour moi, le problème était que mon fichier .png était en train d'être décompressé pour devenir un bitmap vraiment énorme en mémoire, car l'image avait de très grandes dimensions (même si la taille du fichier était minuscule).

Le correctif consistait donc simplement à redimensionner l'image :)

19
petrus-jvrensburg

Cela devrait marcher

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

 mBitmapInsurance = BitmapFactory.decodeFile(mCurrentPhotoPath,options);
16
Akshay komarla

Utilisez Glide Library and Override size à une taille inférieure;

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

Redimensionner votre image avant de configurer ImageView comme ceci:

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

où taille correspond à la taille réelle de ImageView. Vous pouvez atteindre la taille en mesurant:

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

et utilisez les prochaines fonctions imageView.getMeasuredWidth() et imageView.getMeasuredHeight() pour scaling.

8
Vladimir Eremeev

J'ai résolu ce problème en redimensionnant l'image à une taille inférieure. J'utilise la forme xamarin. la diminution de la taille de l’image PNG a résolu le problème.

4
maxspan

J'ai eu l'erreur ci-dessous 

"E/art: projection de OutOfMemoryError" Impossible d'attribuer un octet 47251468 attribution avec 16777120 octets libres et 23 Mo jusqu'à MOO "

après avoir ajouté Android:largeHeap="true" dans AndroidManifest.xml alors je me suis débarrassé de toutes les erreurs

<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

Problème: Impossible d'allouer une allocation de 37748748 octets avec 16777120 octets gratuits et 17 Mo jusqu'au MOO

Solution: 1. Ouvrez votre fichier manifeste 2. à l'intérieur de la balise d'application, il suffit d'ajouter ci-dessous deux lignes

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

Exemple : 

 <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 essayez ceci dans votre fichier manifeste et utilisez 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 = "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">

Utilisez cette bibliothèque

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

Son bon travail de codage 

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

J'ai eu le problème aussi.

Idem avec la plupart des autres personnes ci-dessus . Le problème est causé par une image énorme.

Redimensionnez simplement certaines images, Et nul besoin de changer le code.

2
Mike Yan

Je suis un débutant dans le développement Android, mais j'espère que ma solution aidera, cela fonctionne parfaitement sur mon état. J'utilise Imageview et place l'arrière-plan sur "src" parce que j'essaie de créer une animation par images J'ai eu la même erreur mais quand j'ai essayé de le coder, cela a fonctionné

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 si on utilise 100, alors la résolution d'origine peut arrêter les applications pour manque de mémoire.

si 50 ou moins de 100, la résolution sera de 50% ou inférieure à 100, ce qui empêchera tout problème de mémoire insuffisante.

1
RAHINUR RAHMAN

Mon problème résolu après l'ajout

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

dans le fichier Build.Gradle

1
Midhilaj

Cela a fonctionné pour moi: il suffit de déplacer les images d'un dossier extractible vers drawable-hdpi.

1
Hossein Amini

J'ai rencontré ce problème quand je n'ai pas tué mon ancienne activité en passant à une nouvelle activité. Je l'ai corrigé avec finish();

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

Vous devez changer la taille de l'objet en dessinable. C'est trop gros pour Android à afficher. par exemple. Si vous définissez image, essayez avec moins de pixels. Cela fonctionne pour moi ... Merci. :)

1
Ali Hassan Qureshi

Dans certains cas (par exemple, opérations en boucle), garbage collector est plus lent que votre code. Vous pouvez utiliser une méthode helper à partir de cette réponse à attendre Garbage Collector.

1
Zon

Votre application se bloque parce que la taille de votre image (en Mo ou Ko) est trop grande de sorte qu'elle n'alloue pas d'espace pour cela Donc, avant de coller votre image dans Drawable, il suffit de réduire la taille.

OU 

Vous pouvez ajouter la suite dans la balise d'application à Manifest.xml. 

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

Après l'ajout de cette application ne se plantera pas.

  • toujours utiliser moins d'images de tailles dans App.
  • Si vous ajoutez des images de grande taille dans l'application, vous devez ajouter Syntex ci-dessus, mais la taille de l'application augmentera.
1
rhaldar

J'ai constaté que les images du dossier "dessinable" seraient converties en une image beaucoup plus grande sur les téléphones haute définition. Par exemple, une image de 200k sera rééchantillonnée à une résolution plus élevée, telle que 800k ou 32000k. Je devais le découvrir moi-même et à ce jour, je n'ai pas vu de documentation sur ce piège mémoire. Pour éviter cela, je mets tout dans un dossier drawable-nodpi (en plus d'utiliser "options" dans BitmapFactory en fonction du tas de périphérique particulier). Je ne peux pas me permettre de faire grimper la taille de mon application avec plusieurs dossiers pouvant être tirés, d'autant plus que la gamme de paramètres d'écran est si vaste maintenant. Le problème, c'est que studio n'indique pas spécifiquement le dossier 'drawable-nodpi' en tant que tel dans la vue du projet, mais simplement un dossier 'pouvant être dessiné'. Si vous ne faites pas attention, lorsque vous déposez une image dans ce dossier en studio, elle ne sera pas réellement déposée dans le dessinable-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

Assurez-vous de cliquer jusqu'au dossier nodpi dans la boîte de dialogue, car la vue du projet ne vous montrera pas tous les dossiers dessinés séparément comme auparavant, il ne sera donc pas immédiatement évident que vous vous êtes trompé. Studio a recréé la Vanilla 'drawable' à un moment donné après l'avoir supprimée il y a longtemps:

 enter image description here

1
Androidcoder

ajouter ceci à votre manifeste sous applications? Android: largeHeap = "true"

1
SAURABH OMER

Utilisez une bibliothèque de chargement d’images telle que Picasso ou Glide . L'utilisation de ces bibliothèques empêchera les plantages à l'avenir.

0
Vladyslav Panchenko
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();

Ensuite, dans la balise Application, ajoutez largeheap size = "true

0
sathish mobapp dev

Si vous téléchargez une image, essayez de réduire la qualité de l’image, qui est le deuxième paramètre du bitmap. C'était la solution dans mon cas. Auparavant, c'était 90, puis j'ai essayé avec 60 (comme dans le code ci-dessous).

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

Je suppose que vous voulez utiliser cette image comme une icône. Comme le dit Android, votre image est trop grande. Il vous suffit de redimensionner votre image pour qu'Android sache quelle taille d'image utiliser et à quel moment en fonction de la résolution de l'écran. Pour ce faire, dans Android Studio: 1. Cliquez avec le bouton droit sur le dossier de rés., 2. sélectionnez Image Asset 3. Sélectionnez le type d'icône 4. Attribuez un nom à l'icône. 5. Sélectionnez Image dans le type d'actif. 6. Rognez votre image. Cliquez sur Suivant et terminez. . Dans votre code source ou xml, faites simplement référence à l'image qui se trouvera désormais dans le dossier de présentation ou dans le mipmap en fonction du type d'actif sélectionné. L'erreur disparaîtra.

Essayez le plus simple. Peut-être que votre application se bloque parce que la taille de votre image (en Mo) est trop grande, vous ne devez donc pas allouer d’espace. Donc, avant de coller votre image dans Drawable, il suffit de réduire la taille de n'importe quel logiciel de visualisation ou si vous prenez une image de la galerie au moment de l'exécution, avant de l'enregistrer, comprimez votre bitmap . certainement pour vous sera.

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