web-dev-qa-db-fra.com

java.lang.OutOfMemoryError: la taille du bitmap dépasse VM budget

J'essaie de changer la mise en page de mon application de portrait en paysage et vice-versa. Mais si je le fais fréquemment ou plus d'une fois, mon application se bloque parfois .. Vous trouverez ci-dessous le journal des erreurs. S'il vous plaît suggérer ce qui peut être fait?

 01-06 09:52:27.787: ERROR/dalvikvm-heap(17473): 1550532-byte external allocation too large for this process. 01-06 09:52:27.787: ERROR/dalvikvm(17473): Out of memory: Heap Size=6471KB, Allocated=4075KB, Bitmap Size=9564KB 
 01-06 09:52:27.787: ERROR/(17473): VM won't let us allocate 1550532 bytes 
 01-06 09:52:27.798: DEBUG/skia(17473): --- decoder->decode returned false
 01-06 09:52:27.798: DEBUG/AndroidRuntime(17473): Shutting down VM
 01-06 09:52:27.798: WARN/dalvikvm(17473): threadid=3: thread exiting with uncaught exception (group=0x4001e390)
 01-06 09:52:27.807: ERROR/AndroidRuntime(17473): Uncaught handler: thread main exiting due to uncaught exception
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Java.lang.RuntimeException: Unable to start activity ComponentInfo{}: Android.view.InflateException: Binary XML file line #2: Error inflating class <unknown
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2596) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2621) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.app.ActivityThread.handleRelaunchActivity(ActivityThread.Java:3812) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.app.ActivityThread.access$2300(ActivityThread.Java:126) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1936) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.os.Handler.dispatchMessage(Handler.Java:99) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.os.Looper.loop(Looper.Java:123) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.app.ActivityThread.main(ActivityThread.Java:4595) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Java.lang.reflect.Method.invokeNative(Native Method)
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Java.lang.reflect.Method.invoke(Method.Java:521) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:860) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:618) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at dalvik.system.NativeStart.main(Native Method)
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: Android.view.InflateException: Binary XML file line #2: Error inflating class <unknown
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.view.LayoutInflater.createView(LayoutInflater.Java:513) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at com.Android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.Java:56) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.view.LayoutInflater.createViewFromTag(LayoutInflater.Java:563) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.view.LayoutInflater.inflate(LayoutInflater.Java:385) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.view.LayoutInflater.inflate(LayoutInflater.Java:320) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.view.LayoutInflater.inflate(LayoutInflater.Java:276) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at com.Android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.Java:207) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.app.Activity.setContentView(Activity.Java:1629) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at onCreate(Game.Java:98)
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1047) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2544) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     ...  12 more
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: Java.lang.reflect.InvocationTargetException 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.widget.LinearLayout.<init>(LinearLayout.Java:92) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Java.lang.reflect.Constructor.constructNative(Native Method)
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Java.lang.reflect.Constructor.newInstance(Constructor.Java:446) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.view.LayoutInflater.createView(LayoutInflater.Java:500) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     ...  22 more
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: Java.lang.OutOfMemoryError: bitmap size exceeds VM budget
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.graphics.BitmapFactory.decodeStream(BitmapFactory.Java:464) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.Java:340) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.graphics.drawable.Drawable.createFromResourceStream(Drawable.Java:697) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.content.res.Resources.loadDrawable(Resources.Java:1705) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.content.res.TypedArray.getDrawable(TypedArray.Java:548) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.view.View.<init>(View.Java:1850) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.view.View.<init>(View.Java:1799) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     at Android.view.ViewGroup.<init>(ViewGroup.Java:296) 
 01-06 09:52:27.857: ERROR/AndroidRuntime(17473):     ...  26 more 
25
Angel

L’une des erreurs les plus courantes que j’ai trouvées lors du développement d’applications Android est la 

Java.lang.OutOfMemoryError: la taille du bitmap dépasse le budget VM

erreur. J'ai souvent constaté cette erreur sur des activités utilisant de nombreux bitmaps après avoir modifié l'orientation: l'activité est détruite, créée à nouveau et les présentations sont «gonflées» à partir du XML en utilisant la mémoire VM disponible pour les bitmaps.

Les bitmaps de la structure d'activité précédente ne sont pas correctement désalloués par le récupérateur de mémoire, car ils ont des références croisées avec leur activité. Après de nombreuses expériences, j'ai trouvé une très bonne solution à ce problème.

Tout d’abord, définissez l’attribut «id» sur la vue parent de votre présentation XML:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:layout_width="fill_parent"
        Android:layout_height="fill_parent"
        Android:id="@+id/RootView">
        ...

Ensuite, sur la méthode onDestroy() de votre activité, appelez la méthode unbindDrawables() en transmettant une référence à la vue parent, puis effectuez une opération System.gc().

    @Override
    protected void onDestroy() {
        super.onDestroy();

        unbindDrawables(findViewById(R.id.RootView));
        System.gc();
    }

    private void unbindDrawables(View view) {
        if (view.getBackground() != null) {
            view.getBackground().setCallback(null);
        }
        if (view instanceof ViewGroup) {
            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
                unbindDrawables(((ViewGroup) view).getChildAt(i));
            }
            ((ViewGroup) view).removeAllViews();
        }
    }

Cette méthode unbindDrawables() explore l'arborescence de la vue de manière récursive et:

  1. Supprime les rappels sur tous les éléments dessinables en arrière-plan
  2. Supprime les enfants sur chaque groupe de vues
50
hp.android

J'avais l'erreur Java.lang.OutOfMemoryError: Bitmap Size dépasse VM à plusieurs reprises.

1) Lors du changement d'application et de revenir à l'application quelque temps plus tard (Appuyez sur le bouton d'accueil et après avoir parcouru une URL)

2) Lorsque vous vous connectez/déconnectez-vous fréquemment sur l'application (dans les 10 secondes)

3) Lors de la commutation de l'appareil horizontalement/verticalement

Enfin j'ai résolu l'erreur de la manière suivante

    public void clearAllResources() {

    // Set related variables null

    System.gc();
    Runtime.getRuntime().gc();
   }
12
Rafiq

Ceci est une réponse pratique, ce que j'ai essayé d'éviter ce problème au moment de l'exécution

Runtime.getRuntime().gc();

Appeler Garbage Collector est une bonne idée.

8
Pervez Alam

Ajoutez cette ligne de code au fichier de manifeste Android dans la balise "application": - Android: largeHeap = "true"

<application
         Android:theme="@Android:style/Theme.NoTitleBar"
        Android:allowBackup="true"
        Android:largeHeap="true"
        Android:icon="@drawable/ic_launcher"
        Android:label="@string/app_name"
       >
4
Lins Louis

D'où vient la source de l'image? Avez-vous une image de 9 Mo dans votre dossier drawables?

Il y a beaucoup de discussions sur les problèmes liés à la gestion de la mémoire bitmap native d'Android, par exemple. http://code.google.com/p/Android/issues/detail?id=10821 , http://code.google.com/p/Android/issues/detail?id=8488 , http://groups.google.com/group/Android-developers/browse_thread/thread/ed57849ef705d421/11af8362d77a8cf4?lnk=raot . J'ai eu de la chance en appelant explicitement recycle () et System.gc () chaque fois que j'ai terminé avec un bitmap, par exemple:

private void changeImage() {
     if (mCurrentImage != null) {
          mCurrentImage.recycle();
          mCurrentImage = null;
          System.gc();
     }
     mCurrentImage = getNewImage();
}
3
Daren Robbins

Vous perdez des ressources (probablement l'objet Drawable). Essayez les outils dans Quels outils et méthodes Android fonctionnent le mieux pour détecter les fuites de mémoire/de ressources?

3
J-16 SDiZ

Vous pouvez résoudre le problème en utilisant opts.inSampleSize=2; or opts.inSampleSize=4 

BitmapFactory.Options opts = new BitmapFactory.Options();
// opts.inJustDecodeBounds = true; 
opts.inSampleSize=2;    
Bitmap myBitmap = BitmapFactory.decodeFile(st_imagepath,opts);
3
W00di

Tout d'abord, arrêtez le blocage de votre application au moment de l'exécution en détectant l'erreur OutOfMemory à l'emplacement que vous pensez susceptible de générer cette erreur, comme indiqué ci-dessous:

try {

...

}
catch(OutOfMemoryError error)  {
    //decide what to do when there is not more memory available
}
3
Khawar Raza

J'ai fait quelques extensions de l'excellente réponse de @ hp.Android:

  1. Au lieu de définir un ID RootView dans chaque classe XML, je trouve de manière dynamique la vue racine à l'aide de Android.R.id.content.
  2. Comme @Mario Lenci le dit, AdapterView ne prend pas en charge removeAllViews, je vérifie donc le type de la vue avant d'appeler removeAllViews().
  3. OMI, ce n’est pas une bonne idée d’appeler System.gc() dans chaque appel onDestroy (par exemple cette réponse ), c’est pourquoi j’ai supprimé cela.
  4. J'ai créé une méthode statique onDestroy que j'appelle à partir de onDestroy dans toutes mes classes d'activité personnalisées.
  5. J'ai ajouté une protection supplémentaire contre les erreurs et la journalisation.

Voici le code:

    public static void onDestroy(Activity activity) {
        View rootView = null;

        try {            
            rootView = ((ViewGroup) activity.findViewById(Android.R.id.content))
                    .getChildAt(0);
        } catch (Exception e) {
            Log.w("Cannot find root view to call unbindDrawables on",
                  activity);
        }

        if (rootView != null) {
            Log.d("unbindDrawables", activity, rootView);
            unbindDrawables(rootView);
        }
    }

    /**
      * Utility method to unbind drawables when an activity is destroyed.  This
      * ensures the drawables can be garbage collected.
      */
     public static void unbindDrawables(View view) {
         if (view.getBackground() != null) {
             view.getBackground().setCallback(null);
         }

         if (view instanceof ViewGroup) {
             for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
                 unbindDrawables(((ViewGroup) view).getChildAt(i));
             }

             try {                
                 // AdapterView objects do not support the removeAllViews method
                 if (!(view instanceof AdapterView)) {             
                     ((ViewGroup) view).removeAllViews();
                 }
             } catch (Exception e) {
                 Log.w("Ignore Exception in unbindDrawables", e);
             }
         }
     }
2
Dan J

Angel, il y a un problème similaire posté sur StackOverflow ici @ Exception OutOfMemory lors du chargement d'un bitmap à partir d'un stockage externe

Et à partir de là, j'ai déduit que SoftReference pourrait également être une alternative à la solution. Vérifiez le post, cela pourrait s'avérer utile.

2
Saurabh

http://yekmer.posterous.com/Android-memory-management

peut être aider ce site.Et vous devriez libérer toutes les références.

0
Maidul

Une allocation de 1550532 octets semble grande. Je suppose que votre mise en page fait référence à une image bitmap, un PNG peut-être? Quelles sont les dimensions de ce PNG? S'il est vraiment gros et que vous en avez plusieurs, vous risquez de ne pas avoir assez de mémoire pour les charger tous en même temps.

De plus, si cela est déclenché par la rotation, rappelez-vous que votre activité est détruite et recréée. Vous devrez peut-être faire attention aux références statiques. Jetez un coup d'oeil à ceci blog de Google . Veillez à conserver des références statiques dans votre code, ce qui peut entraîner des fuites.

0
satur9nine