2010-12-03 17 views
5

Ich habe eine Reihe von Ansichten in einem vertikalen LinearLayout. Jede Ansicht generiert und zeichnet ein Bitmap, wenn Sie zu einem Bild scrollen. Aus Performancegründen möchte ich die Bitmap nicht jedes Mal erzeugen, wenn onDraw() aufgerufen wird, aber aus Speichergründen kann ich keine harten Referenzen auf die Bitmaps behalten. Ich könnte Ratschläge zu der Strategie geben, die ich ergreifen sollte.Android: Bitmaps, SoftReferences und OOMs?

Ich habe bereits den offensichtlichen Weg ausprobiert: Erzeugen der Bitmap und dann Umwickeln mit einer SoftReference. Dies ist aus zwei Gründen fehlgeschlagen. 1. Die Referenzen werden viel eifriger gesammelt als erwartet. 2. Ich bekomme immer noch OOMs! Das ist schockierend, da keine Bitmap besonders groß ist. Daher sollte eine einzelne Ansicht nicht das OOM verursachen, was mich dazu veranlasst, anzunehmen, dass das OOM auftritt, weil die anstößigen SoftReference (s) keine Chance hatten, freigegeben zu werden. Das OOM tritt auch auf, wenn meine Anwendung eine zugewiesene Heap-Größe von 6 MB hat (gemäß der DDMS-Ansicht), würde ich erwarten, dass sie auf 16 MB anwächst, bevor OOM geworfen wird.

Irgendwelche Ratschläge?

+0

reg. "hat eine zugewiesene Heap-Größe von 6 MB (nach DDMS-Ansicht)": Lesen Sie meine Antwort auf: http://stackoverflow.com/questions/3238388/android-out-of-memory-exception-in-gallery ... die 6 mb ist nicht die von den Bitmaps zugewiesene Größe. Bitmaps nehmen nativen Heap. –

+0

Vielen Dank, ich habe die in Ihrem Beitrag empfohlene Protokollierungsstrategie ausprobiert. Dies erklärt, warum es bei "6 mb" OOMs gibt. Gemäß Ihrem Logging-Code, es OOMs, wenn meine eigene Nutzung 12 MB erreicht (und meine Anwendung Nutzung ist etwa 4 MB). Was sinnvoll ist, denn das sind 16 MB. Aber wenn meine Bitmaps in SoftReferences sind, sollten sie nicht gesammelt werden, wenn 12 MB erreicht sind ??? – ab11

+0

SoftReferences haben nichts mit der Speichernutzung zu tun. – Falmarri

Antwort

11

Das Problem ist, dass Bitmaps Finalizer verwenden, daher kann es einige GC-Durchläufe dauern, bevor der native Speicher tatsächlich freigegeben wird. Daran arbeiten wir, um es besser zu machen.

+0

Haben Sie in der Zwischenzeit irgendwelche Empfehlungen? Ich nehme an, ich sollte etwas tun: eine globale Spur der Bitmaps behalten und sie manuell freigeben, wenn die Gesamtgröße der Bitmaps gefährlich wird? Irgendwelche Ratschläge, um eine solche Lösung weniger willkürlich zu machen? – ab11

+0

Sie sollten recycle() manuell für die zuletzt verwendeten Bitmaps aufrufen. –

+0

Ich nehme an, recycle() wird es als unbenutzt markieren, und dann wird es aufgeräumt, wenn das nächste Mal der Garbage Collector ausgeführt wird? Wenn ja, wie ist das anders als mit einer SoftReference? – ab11