Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does WeakReference#get() start returning null?

I want to use WeakReferences 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?

  1. As soon as there are no more strong-references to the object? (and GC hasn't occurred yet)
  2. Or when the GC has run and determined that their are no more strong-references to the object?

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.

like image 950
Fabian Zeindl Avatar asked May 23 '13 18:05

Fabian Zeindl


2 Answers

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.

like image 97
Gabe Sechan Avatar answered Sep 19 '22 10:09

Gabe Sechan


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.

like image 30
Andy Thomas Avatar answered Sep 18 '22 10:09

Andy Thomas