Android: Bitmaps, SoftReferences, and OOMs?
Asked Answered
M

1

5

I have a series of views in a vertical LinearLayout. Each view generates and draws a Bitmap, when scrolled to. For performance reasons, I would rather not generate the Bitmap each time onDraw() is called, but for memory reasons I can not keep hard references to the Bitmaps. I could use advice on the strategy that I should take.

I already tried the obvious route of: generating the Bitmap, and then wrapping it with a SoftReference. This failed for two reasons. 1. The references get collected far more eagerly than I would expect. 2. I still get OOMs! Which is shocking, because no Bitmap is particularly large, so a single view should not cause the OOM, making me assume that the OOM occurs because the offending SoftReference(s) had not been given a chance to be freed. Also, the OOM occurs when my application is has an allocated heap size of 6mb (according to DDMS view), I would expect it to grow to 16mb before throwing OOM.

Any advice?

Melo answered 3/12, 2010 at 16:8 Comment(4)
reg. " has an allocated heap size of 6mb (according to DDMS view)": read my reply on: #3238888 ... the 6 mb is not the allocated size taken by the bitmaps. bitmaps take native heap.Ladew
Thank you, I tried the logging strategy recommended in your post. This does explain why it OOMs at "6 mb". According to your logging code, it OOMs when my my native usage reaches 12mb (and my application usage is at about 4mb). Which makes sense, because that is 16mb of usage. However, if my Bitmaps are in SoftReferences, shouldn't they get collected when 12mb is reached???Melo
SoftReferences have nothing to do with memory usage.Massicot
My understanding is that wrapping an object in a SoftReference will instruct the garbage collector to free that object, if memory is needed. And that the garbage collector is run prior to an OOM exception being thrown. Therefore, if an object is in a SoftReference, it should not cause an OOM, because the object should be freed if memory is needed.Melo
Q
11

The problem is that Bitmaps use finalizers, therefore, it might take a couple of GC passes before the native memory is actually released. This is something we are working on making better.

Quillen answered 3/12, 2010 at 17:34 Comment(7)
Do you have any recommendations in the meantime? I assume I should do something like: keep some sort of global track of the bitmaps, and start manually freeing them if the aggregate size of the bitmaps starts to get dangerous? Any advice how to make such a solution less arbitrary?Melo
You should call recycle() manually on the least recently used bitmaps.Quillen
I assume recycle() will mark it as unused, and then it will get cleaned up next time the garbage collector runs? If so, how is this different than using a SoftReference?Melo
I am currently also having this issue. Recycling the bitmap frees the memory immediately, as compared to waiting on the GC to clean it for you. developer.android.com/reference/android/graphics/… Unfortunately, when I recycle I end up getting one of those exceptions that says I was trying to use a recycled bitmap.Scarlatti
Romain, here at ShopSavvy we are creating a large bitmap on our product screen to display the product image. I manually call recycle on each bitmap when the screen is being destroyed, however the native heap never seems to get any smaller. It just grows and grows until eventually the phone gets an OOM (some phones faster than others). Is there any advice you can give? I have ensured that recycle is being called on each bitmap and the finalize method is also subsequently being called which should delete the pointer on the native heap.Flense
Actually this seems to be a problem just with the HTC thunderbolt. The nexus s will eventually garbage collect the bitmap and not get an oom error. Equally as good the evo will do the same thing, but for some reason the HTC thunderbolt does not :-/Flense
You need to break the relation between the imageView and the bitmap attached to it by calling setDrawable(null) on the imageView, then the GC will clean up the bitmap space in the native heapJollification

© 2022 - 2024 — McMap. All rights reserved.