When should I recycle a bitmap using LRUCache?
I believe that when the LRUCache evicts an image to make room for another one, the memory is not being freed.
It won't be, until the Bitmap
is recycled or garbage-collected.
A quick google search reveals that this is happening because the image which is displaying has been recycled.
Which is why you should not be recycling there.
Why are recycled images still in the LRUCache if I'm only recycling them after they've been removed?
Presumably, they are not in the LRUCache
. They are in an ImageView
or something else that is still using the Bitmap
.
What is the alternative for implementing a cache?
For the sake of argument, let's assume you are using the Bitmap
objects in ImageView
widgets, such as in rows of a ListView
.
When you are done with a Bitmap
(e.g., row in a ListView
is recycled), you check to see if it is still in the cache. If it is, you leave it alone. If it is not, you recycle()
it.
The cache is simply letting you know which Bitmap
objects are worth holding onto. The cache has no way of knowing if the Bitmap
is still being used somewhere.
BTW, if you are on API Level 11+, consider using inBitmap
. OutOMemoryErrors
are triggered when an allocation cannot be fulfilled. Last I checked, Android does not have a compacting garbage collector, so you can get an OutOfMemoryError
due to fragmentation (want to allocate something bigger than the biggest single available block).
Image management: When to recycle bitmaps?
The solution I eventually went with was this:
I added the support LRU Cache, and then also added Jake Wharton's DiskLRU Cache. Before images were downloaded from the web, first I checked the memory LRUCache, and then the DiskLRUCache. Any image downloaded was stored in both. Next, every Fragment and Activity that owned any images was registered as a listener to the LRU Cache. If the LRU Cache was going to evict an image to make room for another image, it sent a notification to all the listening Fragments and Activities. These listeners then marked their image as 'dirty', meaning they needed to be re-downloaded, and also then called recycle()
on the bitmap.
This approach seems to work pretty well overall. The app can still get bogged down with garbage collection and eventually after a long time it's still possible to run out of memory on older phones, but it's hard to see where I could improve it any further.
When (if at all) should I use Bitmap.recycle()?
in what situations should I use this method?
The Bitmaps are GC'ed by GC whenever it decides.But in some situations it may get delayed.
And always remember thumb rule in java (Maybe it applies to othe P.L also).The speed of recycling objects by GC may not be same as speed of creating objects.So sometimes the GC is slow to in recycling.
so recycle() means If you want to free memory ASAP you should call recycle()
should I use this method at all??
This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap.But if you are facing the issues like bitmap size exceeded vm budget or out of memory error then you need to use this.
Using LruCache and avoid OutOfMemoryException
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();
}}
Bitmap recycling is not working on android 4.2 or above 4.2?
I had the same problem. Recycle() used to work fine for my bitmap heavy application but now doesn't seem to release the memory even when I leave the activity that they were displayed in.
I solved it by keeping a handle on all the imageViews that I displayed bitmaps in, and now when I leave the activity I not only recycle() the bitmaps I also do a setImageBitmap(null) on all the views that were displaying those bitmaps.
I suspect that recycle() used to reclaim the memory even if something was still referencing the bitmap, but it no longer does that.
Related Topics
Particular Title(Fetched from API) Using Searchview
Android: Support Multiple Screens
Not Enough Space to Show Ad (Admob)
Want to Load Desktop Version in My Webview Using Uastring
Expandablelistview with Viewpager Combination as Its Child
How Open New Activity Clicking an Item in Listview
A Pre-Populated Database Does Not Work at API 28 Throws "No Such Table" Exception
How to Integrate Opencv 4.0 into a Pure C++ Android Ndk Project
Disabling Android's Chrome Pull-Down-To-Refresh Feature
Android: I Want Use My Custom Font with Webviewb
Firebase - How to Delete Many Entries at Once
How to Pass Image Data from One Activity to Another Activity
How to Know the Calling Activity in Android