25

AFAIK on Android, it is recommended to reference Bitmap objects as WeakReferences in order to avoid memory leaks. When no more hard references are kept of a bitmap object, the garbage collector will automatically collect it.

Now, if I understand correctly, the method Bitmap.recycle() must always be called to free a Bitmap. I think this is because Bitmap objects have special memory management.

Is that correct?

If this is true, when using WeakReferences, there must be memory leaks because Bitmap.recycle() is never called when the WeakReferences are freed. Or, somehow, are WeakReferences sufficient to avoid memory leaks?

Thanks

advait
  • 6,355
  • 4
  • 29
  • 39
Sly
  • 2,105
  • 5
  • 22
  • 28

1 Answers1

51

Bitmap.recycle isn't required to be called, as the garbage collector will clean up bitmaps on its own eventually (as long as there are no references). Bitmaps in Android are created in native memory, not on the VM heap, so the actual bitmap object on the VM heap is very small as it doesn't contain any actual bitmap data. (EDIT: no longer the case as of Android 3.0+) The real size of the bitmap will still be counted against your heap usage for purposes of GC and making sure your app doesn't use too much memory.

However, the GC seems to be a little moody when it comes to Bitmaps. If you just remove all hard references, it would sometimes (in my case) hang onto the Bitmaps for a little while longer, perhaps because of the weird way Bitmap objects are allocated/counted. Bitmap.recycle seems to be good for getting the GC to collect that object more quickly.

Either way, you won't leak memory if you don't call Bitmap.recycle as long as you don't keep hard references accidentally. You may encounter OutOfMemoryErrors if you try to allocate too many bitmaps at once or too large bitmaps without calling recycle, though.

EDIT: It is important to note that as of Android 3.0, Bitmaps are no longer allocated in native memory. The are allocated on the VM heap like any other Java object. However, what I said about not needing to call recycle still applies.

Lii
  • 11,553
  • 8
  • 64
  • 88
Victor
  • 1,137
  • 1
  • 10
  • 15
  • Cleared explanations. Thanks a lot ! – Sly Feb 10 '11 at 17:38
  • 1
    I load images with about 20 sec intervals. I call recycle() but Debug.getNativeHeapAllocatedSize() shows that native memory allocation is constantly growing till the OutOfMemoryError – Maxim Jul 14 '11 at 15:51
  • This is flat out NOT TRUE for android < 3.0. If you are using Android < 3.0, you must recycle the bitmap using Bitmap.recycle() as the Garbage Collector has no visibility of the pixel data stored in C array and you will eventually run out of memory on apps that make use of a lot of bitmaps. On Android > 3 you do not have to call recycle, but you must not keep any references to the bitmap beyond the scope of your activity. – Kevin Parker Jun 27 '12 at 17:55
  • 4
    @Kevin: [This 2011 Google I/O talk by Android engineer Patrick Dubroy disagrees.](http://www.youtube.com/watch?v=_CruQY55HOk&feature=player_detailpage#t=699s) Yes, pre-3.0, Bitmaps allocated the memory for pixel data on the native heap (which I mentioned in my original post), with the true size of the Bitmap still being counted against your VM heap usage. However, they still can and will be garbage collected (eventually, assuming you're not holding a hard reference), at which point their finalizer will run and call through to a native method that `free`s the memory on the native heap. – Victor Jun 28 '12 at 00:06
  • Now, that doesn't mean it's not a good idea to call `recycle()`, [since it seems to take a few passes](http://stackoverflow.com/a/4348208/143987) for the GC to decide to collect Bitmaps pre-3.0 and call their finalizers, and if you allocate too many or too large Bitmaps before the GC properly frees up unused ones, you will probably run into OutOfMemoryErrors. But, my answer to the original question (you **must** call recycle or you'll leak memory ) is still accurate, because Bitmaps pre-3.0 will *eventually* be GC'd even if you don't call recycle. – Victor Jun 28 '12 at 00:10
  • Please take a look there. The bitmap would be eventually recycled but it is happening in finalizer so it might be long time when that is called. And you may run into OOM as I think finalizers are not guaranteed to run. http://androidxref.com/2.1/xref/frameworks/base/graphics/java/android/graphics/Bitmap.java#990 – marekdef Dec 21 '12 at 14:42