Android OutOfMemoryError:?

Lesezeit: 10 Minuten

Android OutOfMemoryError
NagarjunaReddy

Ich bekomme sporadisch eine OutOfMemoryError: (Heap Size=49187KB, Allocated=41957KB) in einer meiner Apps. Was kann ich tun, um dies zu diagnostizieren?

  01-09 10:32:02.079: E/dalvikvm(8077): Out of memory: Heap Size=49187KB, Allocated=41957KB, Limit=49152KB
  01-09 10:32:02.079: E/dalvikvm(8077): Extra info: Footprint=48611KB, Allowed Footprint=49187KB, Trimmed=7852KB
  01-09 10:32:02.079: D/skia(8077): --- decoder->decode returned false
  01-09 10:32:02.079: D/AndroidRuntime(8077): Shutting down VM
  01-09 10:32:02.079: W/dalvikvm(8077): threadid=1: thread exiting with uncaught exception (group=0x40a97228)
  01-09 10:32:02.079: E/AndroidRuntime(8077): FATAL EXCEPTION: main
  01-09 10:32:02.079: E/AndroidRuntime(8077): java.lang.OutOfMemoryError: (Heap Size=49187KB, Allocated=41957KB)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:486)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:773)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at android.content.res.Resources.loadDrawable(Resources.java:2044)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at android.content.res.Resources.getDrawable(Resources.java:675)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at android.view.View.setBackgroundResource(View.java:11776)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at com.blsk.bigtoss.ImageLoader.DisplayImage(ImageLoader.java:81)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at com.blsk.bigtoss.MatchActivity$MatchAsyncTask.onPostExecute(MatchActivity.java:1768)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at android.os.AsyncTask.finish(AsyncTask.java:602)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at android.os.AsyncTask.access$600(AsyncTask.java:156)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at android.os.Handler.dispatchMessage(Handler.java:99)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at android.os.Looper.loop(Looper.java:156)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at android.app.ActivityThread.main(ActivityThread.java:4987)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at java.lang.reflect.Method.invokeNative(Native Method)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at java.lang.reflect.Method.invoke(Method.java:511)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
  01-09 10:32:02.079: E/AndroidRuntime(8077):   at dalvik.system.NativeStart.main(Native Method)
  01-09 10:32:02.099: E/EmbeddedLogger(1612): App crashed! Process: com.blsk.bigtoss
  01-09 10:32:02.099: E/EmbeddedLogger(1612): App crashed! Package: com.blsk.bigtoss v6 (1.2)
  01-09 10:32:02.129: E/EmbeddedLogger(1612): Application Label: Cricket

Dies ist die Zeile, in der es passiert:

LinearLayout resultMatchHeaderContainer = new LinearLayout(activity); 

if (!resultImagePath.equals("")) {   
    imageLoader.DisplayImage(resultImagePath,resultMatchHeaderContainer, -1,modifiedHeight, R.drawable.matches_placeholder_result2x);
} else {
    try {
        resultMatchHeaderContainer.setBackgroundResource(R.drawable.matches_placeholder_result2x); 
    } catch (OutOfMemoryError e) {         
        e.printStackTrace();
    }
}

  • Sie versuchen, eine Bitmap in eine ImageView zu laden. Offensichtlich ist die Bitmap, die Sie manchmal laden, zu groß, um in den Speicher zu passen. Sie müssen das Bild beim Lesen verkleinern. Sehen Sie sich inSampleSize an

    – Greg Ennis

    9. Januar 14 um 5:12 Uhr

  • @NagarjunaReddy hast du dein Problem gelöst oder nicht?

    – dipali

    9. Januar 14 um 5:28 Uhr

  • Nein, noch nicht versucht … @dipali

    – NagarjunaReddy

    9. Januar 14 um 5:30 Uhr

  • was? hast du dein prblm nicht gelöst?

    – dipali

    9. Januar 14 um 5:34 Uhr

  • Dieser Fehler tritt nur manchmal auf, nicht immer @dipali

    – NagarjunaReddy

    9. Januar 14 um 5:43 Uhr

vielleicht hilft dir das weiter?

Manifest hinzufügen

Android > v3

<application
    ....
       android:largeHeap="true"> 

  • Die Verwendung von largeHeap wird nicht in allen Fällen empfohlen, verwenden Sie es bitte sehr vorsichtig, da es andere laufende Anwendungen verlangsamen und auch die Reaktionsfähigkeit Ihrer App beeinträchtigen kann, da der Garbage Collector häufiger angefordert wird. Weitere Informationen finden Sie in dieser Rede von Google i/o youtube.com/watch?v=_CruQY55HOk

    – Laune

    17. Juli 15 um 12:49 Uhr

  • Fordern Sie niemals einen großen Heap an, nur weil Ihnen der Arbeitsspeicher ausgeht und Sie eine schnelle Lösung benötigen – Sie sollten ihn nur verwenden, wenn Sie genau wissen, wo Ihr gesamter Arbeitsspeicher zugewiesen wird und warum er beibehalten werden muss. Doch selbst wenn Sie sicher sind, dass Ihre App den großen Haufen rechtfertigen kann, sollten Sie es so weit wie möglich vermeiden, sie anzufordern. sehen developer.android.com/training/articles/memory.html

    – Adnan Ali

    5. September 16 um 10:41 Uhr


Android OutOfMemoryError
CommonSenseCode

Häufige Korrekturen:

1. Korrigieren Sie Ihre Kontexte:

Versuchen Sie es mit dem passenden Kontext: Zum Beispiel, da ein Toast in vielen Aktivitäten statt nur in einer zu sehen ist, verwenden Sie ihn getApplicationContext() für Toasts, und da Dienste weiterlaufen können, obwohl eine Aktivität beendet ist, starten Sie einen Dienst mit:

Intent myService = new Intent(getApplicationContext(), MyService.class)

Verwenden Sie diese Tabelle als Kurzanleitung für den geeigneten Kontext:
Geben Sie hier die Bildbeschreibung ein

Original Artikel zum Kontext hier.

2. Überprüfen Sie, ob Sie Ihre Dienste tatsächlich beenden.

Zum Beispiel habe ich einen IntentService, der Google Location Service API verwendet. Und ich habe vergessen anzurufen googleApiClient.disconnect();:

//Disconnect from API onDestroy()
    if (googleApiClient.isConnected()) {
        LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, GoogleLocationService.this);
        googleApiClient.disconnect();
    }

3. Überprüfen Sie die Verwendung von Bildern und Bitmaps:

Wenn Sie Quadrate verwenden Bibliothek Picasso Ich habe festgestellt, dass ich Speicher verloren habe, indem ich die nicht verwendet habe .fit(), das meinen Speicherbedarf drastisch von durchschnittlich 50 MB auf weniger als 19 MB reduziert hat:

Picasso.with(ActivityExample.this)                   //Activity context
                .load(object.getImageUrl())           
                .fit()                                //This avoided the OutOfMemoryError
                .centerCrop()                         //makes image to not stretch
                .into(imageView);

4. Wenn Sie Rundfunkempfänger verwenden, deregistrieren Sie diese.

5. Wenn Sie verwenden java.util.Observer (Beobachtermuster):

Unbedingt verwenden deleteObserver(observer);

1642462268 72 Android OutOfMemoryError
Avtar Guleria

Sie können Folgendes tun, um dies zu vermeiden.

Drawable drawable = resultMatchHeaderContainer.getDrawable();

if (drawable instanceof BitmapDrawable) {
    BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
    if (bitmapDrawable != null) {
        Bitmap bitmap = bitmapDrawable.getBitmap();

        if (bitmap != null && !bitmap.isRecycled())
           bitmap.recycle();
    }
}

Das Laden von Bitmaps in der Bildansicht war schon immer eine Ursache für Speichermangel. Dies ist sehr häufig, daher müssen wir Bildansichten und Bitmaps sehr sorgfältig behandeln. Was Sie tun können, ist, während Sie eine beliebige Hintergrund-Bitmap für Ihre Bildansicht festlegen, zuerst das Drawable abrufen und es recyceln, damit es aus dem Speicher entfernt wird, und dann die neue Bitmap festlegen. Dies hilft, OOM-Probleme zu vermeiden. Weiter. Sie können BitmapFactoryOptions verwenden, um die Größe Ihrer Bitmap zu reduzieren. mögen:

// decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f) {
    try {
        // decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        FileInputStream stream1 = new FileInputStream(f);
        BitmapFactory.decodeStream(stream1, null, o);
        stream1.close();

        // Find the correct scale value. It should be the power of 2.
        int width_tmp = o.outWidth, height_tmp = o.outHeight;
        int scale = 1;
        while (true) {
            if (width_tmp / 2 < REQUIRED_WIDTH
                    || height_tmp / 2 < REQUIRED_HIGHT)
                break;
            width_tmp /= 2;
            height_tmp /= 2;
            scale *= 2;
        }

        // decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        FileInputStream stream2 = new FileInputStream(f);
        Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2);
        stream2.close();
        return bitmap;
    } catch (FileNotFoundException e) {
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

  • Warum es abgelehnt wird, lassen Sie mich auch den Grund dafür wissen. Wer es abgelehnt hat, erwähnt bitte den Grund dafür.

    – Avtar Guleria

    9. Januar 14 um 5:18 Uhr

  • Obwohl dies in der Theorie eine nette Idee ist, funktioniert es in der Praxis nicht so gut. Der Aufruf von Recycle() ist lediglich ein Hinweis an den GC, Speicher zurückzufordern. Es kann sein, dass es nicht zurückgefordert wird, wenn Sie Ihr neues Image erstellen, und kann daher immer noch zum Absturz Ihrer Anwendung führen. Noch wichtiger ist jedoch, dass der GC den Speicher automatisch zurückfordert, wenn er über die nächsten paar CG-Zyklen läuft.

    – Das es

    9. Januar 14 um 5:37 Uhr

  • Wirklich, warum jemand runtergestimmt hat, er / sie ist ein echter Nerd.. Meistens funktioniert es.. Es hat für mich funktioniert.. in meinem Projekt..

    – Shakeeb Ayaz

    9. Januar 14 um 5:45 Uhr


  • Ich wollte das gleiche beantworten, also +1

    – Shakeeb Ayaz

    9. Januar 14 um 5:47 Uhr

  • Danke. Shakeeb Ayaz. @TheIT, meinst du, dass die Recycling-Methode auf Bitmap nicht nützlich ist oder was, wenn das dann in welcher Situation wir es verwenden sollten?

    – Avtar Guleria

    9. Januar 14 um 5:51 Uhr

Bevor Sie Bilder in den Speicher laden, komprimieren Sie Ihre Bilder mit

Bitmap original = BitmapFactory.decodeStream(getAssets().open("1024x768.jpg"));
ByteArrayOutputStream out = new ByteArrayOutputStream();
original.compress(Bitmap.CompressFormat.PNG, 100, out);
Bitmap decoded = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));

Log.e("Original   dimensions", original.getWidth()+" "+original.getHeight());
Log.e("Compressed dimensions", decoded.getWidth()+" "+decoded.getHeight());  

Wenn Sie Ihre Bitmap von einer Ressource beziehen, hängt die Bitmap-Dimension in diesem Fall von der Bildschirmdichte des Telefons ab

Bitmap bitmap=((BitmapDrawable)getResources().getDrawable(R.drawable.img_1024x768)).getBitmap();
Log.e("Dimensions", bitmap.getWidth()+" "+bitmap.getHeight());

1642462268 359 Android OutOfMemoryError
Magnus

Dies kann mehrere Gründe haben, möglicherweise behalten Sie Verweise auf andere Teile Ihres Codes zu lange bei. Möglicherweise laden Sie zu große Bitmaps, die zusammen mit Festhalten an vielen Referenzen gibt dir OOM usw.

Normalerweise, wenn ein OOM auftritt a hprof (Schnappschuss des Heap) wird im Stammverzeichnis der SD-Karte (oder im internen Speicher, wenn keine SD-Karte vorhanden ist) erstellt, die von Tools wie gelesen werden kann Eklipse MAT (in den Android-Tools enthalten, wenn Sie Eclipse verwenden). Zuerst muss man evtl. die hprof mit umwandeln hprof-conv Werkzeug. Hier ist ein Tutorial zur Verwendung von Eclipse MAT: Untersuchung Ihrer RAM-Nutzung. Der Bericht über Leckverdächtige ist eine gute erste Lektüre, wenn hprof in Eclipse MAT geladen wird

Nach der Profilerstellung konnten Sie nachlesen, wie Sie Bilder effektiv laden Bitmaps effizient darstellen

Es gibt auch mehrere beliebte Bildladebibliotheken wie z universeller Bildlader und Picasso verfügbar, die mit Leichtigkeit das tun, was Sie brauchen.

  • @NagarjunaReddy hat diese Antwort mit weiteren Ideen aktualisiert, was Sie tun könnten. Ich würde mit der Analyse beginnen hprof Um zu sehen, ob Sie an zu vielen Refs festhalten, können Sie, wenn dies nicht der Fall ist, einige Bildbibliotheken verwenden, die Bilder zwischenspeichern und sie problemlos an Ihre erforderlichen Ansichtsgrößen anpassen.

    – Magnus

    9. Januar 14 um 20:06 Uhr


1642462268 3 Android OutOfMemoryError
BENUTZER9561

letztes Bitmap-Lächeln = BitmapFactory.decodeResource(getResources(), R.drawable.emo_im_happy);

Anruf

String pathname=BitMapToString(smile);

und dann anrufen

setImagesNew(linearview,pathname,activity);

public String BitMapToString(Bitmap bitmap) { 
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
             bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); 
        byte[] b = baos.toByteArray();
      String temp = Base64.encodeToString(b, Base64.DEFAULT);
      return temp;
 }


 public static void setImagesNew(LinearLayout linearLayout, String pathName,
                Activity activity) {

            Bitmap bmp = decodeSampledBitmapFromResource(pathName,
                    getDeviceWidth(activity), getDeviceHeight(activity));

linearLayout.setBackgroundDrawable(bmp);


            bmp = null;
            System.gc();
            Runtime.getRuntime().gc();

        }
    public static Bitmap decodeSampledBitmapFromResource(String pathName,
            int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(pathName, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth,
                reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(pathName, options);
    }

    public static int calculateInSampleSize(BitmapFactory.Options options,
            int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and
            // keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }

    @SuppressLint("NewApi")
    public static int getDeviceWidth(Activity activity) {
        int deviceWidth = 0;

        Point size = new Point();
        WindowManager windowManager = activity.getWindowManager();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            windowManager.getDefaultDisplay().getSize(size);
            deviceWidth = size.x;
        } else {
            Display display = windowManager.getDefaultDisplay();
            deviceWidth = display.getWidth();
        }
        return deviceWidth;
    }

    @SuppressLint("NewApi")
    public static int getDeviceHeight(Activity activity) {
        int deviceHeight = 0;

        Point size = new Point();
        WindowManager windowManager = activity.getWindowManager();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            windowManager.getDefaultDisplay().getSize(size);
            deviceHeight = size.y;
        } else {
            Display display = windowManager.getDefaultDisplay();
            deviceHeight = display.getHeight();
        }
        return deviceHeight;
    }

Bitte legen Sie alle Funktionen in Ihre Aktivität und rufen Sie nur an setImageNew() und Parameter in imageview, sdcardpathname und activity übergeben

Ich hoffe, es wird nicht abstürzen, nachdem Sie diesen Code implementiert haben. weil ich das gleiche problem habe wie du..

  • @NagarjunaReddy hat diese Antwort mit weiteren Ideen aktualisiert, was Sie tun könnten. Ich würde mit der Analyse beginnen hprof Um zu sehen, ob Sie an zu vielen Refs festhalten, können Sie, wenn dies nicht der Fall ist, einige Bildbibliotheken verwenden, die Bilder zwischenspeichern und sie problemlos an Ihre erforderlichen Ansichtsgrößen anpassen.

    – Magnus

    9. Januar 14 um 20:06 Uhr


1642462268 107 Android OutOfMemoryError
Selvan

Dies kann passieren, wenn die Bitmap-Ressource nicht ordnungsgemäß verworfen wird. Es ist besser, die Abmessungen zu lesen, um zu sehen, ob es zum Speicher passt.
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

.

525970cookie-checkAndroid OutOfMemoryError:?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy