[OFFEN] Bitmap.recycle funktioniert nach drawBitmap nicht

H

HighBaer

Neues Mitglied
0
Hallo Leute!

Ich weiß nicht mehr weiter, vielleicht habt Ihr ja noch eine Idee.

Ich entwickle eine App, die zu bestimmten Objekten Fotos anzeigt. Diese Fotos befinden sich als JPEG bereits auf dem Smartphone. Es wird immer nur ein Foto geladen und in einem eigenen View angezeigt. Da die App grundsätzlich hochkannt läuft die Fotos aber im Querformat ("Landscape") angezeigt werden, wird die Ausgabe entsprechend per App gedreht.

Wenn ich das Foto nicht mehr benötige, also wenn der betreffenden View verlassen wird, wird für das entsprechende Bitmap recycle() aufgerufen:
Code:
if (FBmpFoto != null) {
    FBmpFoto.recycle();
    FBmpFoto = null;
    Runtime.getRuntime().gc();
} // if

Nur wird der Speicher trotz recycle() nicht freigegeben. So kommt es dann nach einer Weile zum OutOfMemory-Fehler.
Wenn man sich FBmpFoto im Debuger ansieht, so gibt es eine Eigenschaft "mBuffer" in der wohl das eigentliche Bitmap abgespeichert ist und in dem Fall so um die 6 MB groß ist. Auch nach dem Aufruf von "recycle()".

Wenn ich aber FBmpFoto nicht mit drawBitmap() ausgeben, in dem ich die Prorgammzeile auskommentiere, funktioniert recycle() wie es soll, die Eigenschaft mBuffer zeigt dann auf "null" und gc() gibt die 6 MB frei. Es sieht so aus, als würde es durch das drawBitmap() noch irgend einen Verweis auf FBmpFoto geben, der verhindert, dass recycle() den Buffer leer.

Wenn man mal in den Source (V23) bei recycle() nach sieht:
Code:
public void recycle() {
    if (!mRecycled && mFinalizer.mNativeBitmap != 0) {
        if (nativeRecycle(mFinalizer.mNativeBitmap)) {
            // return value indicates whether native pixel object was actually recycled.
            // false indicates that it is still in use at the native level and these
            // objects should not be collected now. They will be collected later when the
            // Bitmap itself is collected.
            mBuffer = null;
            mNinePatchChunk = null;
        }
        mRecycled = true;
    }
}

Nach dem Kommentar scheint es so, dass das Bitmap noch auf einem "native level" verwendet wird. Es wird auch nicht später freigegeben. :sad:

Hat jemand eine Idee, warum drawBitmap() einen aktiven Verweis auf das native Bitmap hinterlässt uind wie man es verhindern oder aufheben kann?

Kann man noch irgenwie anderes das Bitmap freigeben?

Gibt es irgendeine Möglichkeit das Canvas-Objekt (was vermutlich der Übeltäter ist) zu zerstören oder zumindest zu veranlassen, den Verweis auf das Bitmap zu löschen?
 
Zuletzt bearbeitet von einem Moderator:
Moin, nur als Hinweis: Wenn du oben rechts im Editor sagst "Zum ASCII Editor wechseln" kannst du die Codeteile besser lesbar formatieren. Hab das grad mal fix gemacht. ;)
 
Hallo HighBear.

recycle gibt dir NICHT unmittelbar den Speicher frei, sondern weisst nur an , dass der Speicher
beim nächsten mal durch das System verwendet werden kann .

Ein recht elegante Abhilfe ist LRUCache :
LruCache | Android Developers

Auch kannst du Glide dafür recht einfach einsetzten
GitHub - bumptech/glide: An image loading and caching library for Android focused on smooth scrolling

Hinweis : ein Bitmap Object besitzt auch nicht das decomprimierte Image , sonder nur das komprimierte.
erst wenn es gerendert wird , wird es entpackt.
 
Zuletzt bearbeitet:
Wenn das nicht funktioniert, schreib in das Manifest folgende Zeile:

android:largeHeap="true"

<application> | Android Developers

Der Befehl vergrößert den verfügbaren Heap, den eine App anfordern darf. Gerade Bilder brauchen relativ viel Speicher. Ob das eine guter Weg ist, gibt es im Netz recht viele Diskussionen. An deiner Stelle würde ich es aber mal probieren.

Der Aufruf von des GC gibt den Speicher nicht automatisch sofort frei, sondern ist nur eine Anforderung an das System, den Speicher zu einem möglichst nahen Zeitpunkt freizugeben. (System.gc(), ist eine bessere Variante als Runtime.getRuntime().gc();)

Ich würde auch nochmal deine Views überprüfen, ob sie im Speicher freigeben wurden.
 

Ähnliche Themen

SaniMatthias
Antworten
19
Aufrufe
962
swa00
swa00
O
Antworten
15
Aufrufe
2.973
ORHUX
O
5
Antworten
22
Aufrufe
1.423
590239
5
Zurück
Oben Unten