2

There's an activity in my app whose showing around 1000 very small sized bitmaps (Around 20kb each bitmap). After it loads some of the bitmaps, there's an OutOfMemoryException.

I was first reading about SoftReference and it looked like it will solve my problem about the OOM exceptions. But then, I read that it won't cache my bitmaps and will free them "too soon", so it will have to decode the bitmap again and "waste" time.So, I implemented the LruCache.

How can I make sure that I will not get OOM exception when implementing my LruCache?

Maybe I should just use the SoftReference, because my main target is to avoid OOM

Or, this might be my solution? LruSoftCache

Kara
  • 6,115
  • 16
  • 50
  • 57
idish
  • 3,190
  • 12
  • 53
  • 85

1 Answers1

2

When implementing LruCache, you should specify the cache size, and tell it how to calculate the size for each object (in this case, the object is bitmap).

You can use the following sample:

// uses 1/8th of the memory for the cache
final int cacheSize = (int) (Runtime.getRuntime().maxMemory() / 8L);
LruCache bitmapCache = new LruCache(cacheSize) {
   protected int sizeOf(String key, Bitmap value) {
       return value.getByteCount();
}}
xizzhu
  • 895
  • 6
  • 9
  • What happens if it exceeds the specified memory? does it free the other allocated bitmaps to avoid the memory exception? – idish Oct 15 '13 at 17:54
  • Yes, the least recent used bitmap will be removed from the cache, and will be garbage collected if it's not referenced by other objects. – xizzhu Oct 15 '13 at 17:56
  • "will be garbage collected" means that it will be recycled? bitmap.recycle() – idish Oct 15 '13 at 17:58
  • As you can see here, there's a chance for an outofmemory exception, when using LruCache, it garbage collects the bitmap but doesn't recycle it. http://stackoverflow.com/questions/10743381/when-should-i-recycle-a-bitmap-using-lrucache – idish Oct 15 '13 at 18:05
  • 1
    As far as I know, `bitmap.recycle()` is only needed for pre-honeycomb devices, where the bitmap is not stored in JVM, so there's a chance that you'll get OOM even if no object is referencing the bitmap, but the heap is not freed yet. Then if you're targeting those devices, you need to have some reference counter for the bitmap yourself. – xizzhu Oct 15 '13 at 18:07
  • Actually, I am targeting also pre-honeycomb devices (min api level is 9), do I have to use the following LruCache for pre-honeycomb:http://developer.android.com/reference/android/support/v4/util/LruCache.html and use the following LruCache for honeycomb and on? http://developer.android.com/reference/android/util/LruCache.html or..? – idish Oct 15 '13 at 18:24
  • well, if your min api level is 9, you have to use the support package. – xizzhu Oct 15 '13 at 18:49
  • I don't quite understand why there's also a package for honeycomb devices. Why there are 2 of those LruCache? – idish Oct 15 '13 at 19:37
  • Sorry for digging too much about this, but it is a very important part of my app, to prevent those OOM. I wouldn't care if only pre-honeycomb devices might get OOM, but I want to assure that it won't happen on honeycomb devices and on. If I still use the support package and not the other one (the util), will it be OK? – idish Oct 15 '13 at 21:20
  • The `LruCache` class was introduced in API level 12, so you can't use it in older devices. That's why Android devs backported it to the support package so that you can use it for API level 4 and above (including API level 12 and above). For the OOM issue, if you use `LruCache` for honeycomb and above, you don't need to call `recycle()` at all; but for pre-honeycomb devices, you need to call if no one is referencing the bitmap to make sure it's immediately released. – xizzhu Oct 16 '13 at 06:30