Ich erhalte einen merkwürdigen "Out of Memory" -Fehler beim Dekodieren einer aufzeichnbaren Bildressource 960x926px jpg, die 3555856 Byte zuweist. Das Bild wird nur in drawable-xxhdpi (3x) platziert und ich verwende ein hdpi (1,5x) Gerät. Zwei Fragen:
Warum bekomme ich den Fehler, obwohl ich genug freien Speicher im Heapspeicher habe?
Zuweisung für ein hdpi Gerät sollte ((960/2) x (926/2)) x 4 = 888960 Bytes (nicht 3555856) sein?
Kann mir jemand das erklären?
HINWEIS: Bei der Frage geht es darum, warum ein OOM für 3,5 MB zugewiesen wird, während 22,5 MB freier Speicher zur Verfügung stehen (siehe Protokoll)
03-18 17: 30: 15.050 32750-32750 /? D / dalvikvm: GC_FOR_ALLOC befreit 10809K, 49% frei 23735K / 46087K, pausiert 89ms, insgesamt 89ms
03-18 17: 30: 15.050 32750-32750 /? I / dalvikvm-heap: Erzwingen der Sammlung von SoftReferences für 3555856-Byte-Zuweisung
03-18 17: 30: 15.160 32750-32750 /? D / dalvikvm: GC_BEFORE_OOM befreit 29K, 49% frei 23705K / 46087K , 103ms pausiert, insgesamt 103ms
03-18 17: 30: 15.160 32750-32750 /? E / dalvikvm-heap: Nicht genügend Arbeitsspeicher auf a 3555856-Byte-Zuweisung .
03-18 17: 30: 15.160 32750-32750 /? I / dalvikvm: "Haupt" prio = 5 tid = 1 RUNNABLE
03-18 17: 30: 15.160 32750-32750 /? I / dalvikvm: | group="Haupt" sCount = 0 dsCount = 0 obj = 0x418fc6a0 selbst = 0x4010c008
03-18 17: 30: 15.160 32750-32750 /? I / dalvikvm: | sysTid = 32750 nice = 1 sched = 0/0 cgrp = apps handle = 1075251280
03-18 17: 30: 15.160 32750-32750 /? I / dalvikvm: | schedstat = (0 0 0) utm = 3807 stm = 859 Kern = 0
03-18 17: 30: 15.160 32750-32750 /? I / dalvikvm: um android.graphics.BitmapFactory.nativeDecodeAsset (Native Methode)
03-18 17: 30: 15.160 32750-32750 /? I / dalvikvm: um android.graphics.BitmapFactory.decodeStream (BitmapFactory.java:636)
03-18 17: 30: 15.160 32750-32750 /? I / dalvikvm: um android.graphics.BitmapFactory.decodeResourceStream (BitmapFactory.java:484) 03-18 17: 30: 15.160 32750-32750 /? I / dalvikvm: um android.graphics.BitmapFactory.decodeResource (BitmapFactory.java:512)
03-18 17: 30: 15.160 32750-32750 /? I / dalvikvm: um android.graphics.BitmapFactory.decodeResource (BitmapFactory.java:542)
1) Wenn Sie keine kleinere Version im Ordner hdpi haben, wird die engste Übereinstimmung verwendet. Es wird also die xxhdpi verwenden, wenn keine hdpi oder eine drawbare / version existiert.
2) Es wird nicht automatisch skaliert. Es wird in voller Größe angezeigt.
3) Wenn dies eine OOM verursacht, verwenden Sie wahrscheinlich zu viel Speicher im Allgemeinen.
Der Grund, warum Sie OOM erhalten, ist, dass wenn das Bild in den Speicher decodiert wird, seine Bitmap mehr Größe als die Bildauflösung hat (fast 4 Mal bin ich nicht sicher über diesen Wert).
Bei der Arbeit mit Bildern sind einige Punkte zu beachten:
Versuchen Sie also, die folgende Lösung zu verwenden:
Schritt 1: Suchen Sie die Bildschirmgröße
Entnommen aus hier
%Vor%Schritt 1: Erstellen Sie eine asynchrone Aufgabe zum Dekodieren von Bitmap
Wenn Sie eine Async-Aufgabe als innere Klasse verwenden, sollten Sie die Verwendung der öffentlichen statischen inneren Klasse in Erwägung ziehen (um Speicherleckprobleme zu vermeiden) und die schwache Referenz der Bildansicht beibehalten, in die das Bild geladen werden soll. Übergeben Sie auch die Bildressource oder -datei oder den Stream, den Sie dekodieren möchten, an den Konstruktor. Im folgenden Code wird davon ausgegangen, dass Sie eine Ressource dekodieren möchten. Übergeben Sie auch die in Schritt 1 berechnete Breite und Höhe.
%Vor%Referenzen:
Die Speichergröße der Bitmap beträgt Breite x Höhe x Bits pro Farbe. Ich glaube, Sie haben keine bestimmte Option verwendet, da Sie 4 Bytes pro Pixel verwenden (Rot 1 Byte, Grün 1 Byte, Blau 1 Byte, Alpha 1 Byte). Also: 960 * 926 * 4 = 3555840 Bytes.
Über deinen OOM: Was mir nicht so bekannt vorkommt ist:
Erzwingen der Sammlung von SoftReferences für 3555856-Byte-Zuweisung
Wo speichern Sie die zugewiesene Bitmap? Soft-Referenzen sollten auf Android vermieden werden.
Nach dem Vorschlag von Gabe Sechan würde ich empfehlen, eine Website wie makeappicon zu verwenden, mit der Sie jedes Bild, das zu groß ist, automatisch skalieren können . Es ist ein nützliches Tool, obwohl Android diese Skalierungsprobleme für Sie behandeln sollte.
Mimmo Grottoli hat recht, was die ARGB-Bytes angeht, also muss ich mir da, soweit ich das beurteilen kann, keine Sorgen machen.
Der Grund, warum Sie diesen Fehler am wahrscheinlichsten haben, ist ein bedeutender Speicherverlust, der beim Erstellen (und nicht beim Zerstören) von Bitmaps eine Rolle spielt, die ich vor einiger Zeit aus einem Steg-Projekt gelernt habe.
Um diesen Speicher zu bereinigen, können Sie die onDestroy()
-Methode für Ihre Aktivität / Ihr Fragment überschreiben, oder Sie können dies bei Bedarf manuell tun.
Ich hoffe, er hat dir geholfen.
Tags und Links android android-bitmap android-image bitmapfactory android-memory