Reputation: 5988
I want to use WeakReference
s as part of an (android) bitmap-cache to be able to check when a bitmap isn't used anymore.
My cache has a maximum-size that is smaller than the Java heap-space. When a new bitmap would overflow the cache, it should let go of bitmaps that aren't needed anymore.
My question: When does the get()-method of a WeakReference
return null?
If 2. is true than I could run into the situation that my cache could fill up and GC hasn't recently run for some reason.
Then even if I had already let go of references AFTER the last GC run, WeakReference#get()
would still return the object and my cache wouldn't clear it out.
Upvotes: 14
Views: 8324
Reputation: 1215
As stated in the other answers, a WeakReference will return null once the pointed object has no more strong/soft references and the GC has reclaimed memory.
On a more general rule, I don't think Weak/SoftReferences are a good thing in an application. It makes your mix concerns :
When you start to use Weak/Soft references, you introduce memory-managed concerns within your application, which makes it harder to develop/debug/understand.
You might want to have a fixed-size (number of elements or bitmap size) LRU cache instead.
Hope that helps !
Upvotes: -3
Reputation: 93614
The answer is it depends on what version of Android you're using. Somewhere in the 2.3 timeframe, Android changed its handling or weak references. Previously, it deleted them when the GC ran. As of some version of 2.3 (2.3.3?) it started deleting them immediately upon the last strong reference going away. So in modern versions of Android, weak references are useless.
Before this change, weak references were used for caching. They no longer work. The correct way now is to use an LRUCache. If you need to support older versions, use the support library to backport the LRU cache.
After some searching, I think the change was made in 3.0, not 2.3. Still, the solution is the same.
Upvotes: 14
Reputation: 1271
To cache bitmaps use SoftReference rather than Weak. GC would clear WeakReference as soon as it looses all its Strong and Soft references which might destroy the purpose of caching. SoftReference are cleared only if there is low memory.And it is guaranteed that the GC would be run before throwing a OOME.
Upvotes: 5
Reputation: 86419
The WeakReference is cleared as soon as the GC has determined that the object is weakly reachable.
This is close to your second case. However, weak reachability requires not just the absence of strong references, but also the absence of soft references.
From the Java package documentation for java.lang.ref:
Soft and weak references are automatically cleared by the collector before being added to the queues with which they are registered, if any.
...
An object is weakly reachable if it is neither strongly nor softly reachable but can be reached by traversing a weak reference. When the weak references to a weakly-reachable object are cleared, the object becomes eligible for finalization.
Upvotes: 5