Search code examples
javareferenceweak-referencessoft-references

How to determine reference reachability in java


In Java, how to determine reference reachability in some complicated cases such as reference chain?

Suppose in the following example, str is the referent of a software reference sr and sr is a referent of a weak reference wr.

String str = "abc";
SoftReference<Object> sr = new SoftReference<>(str);
WeakReference<Object> wr = new WeakReference<>(sr);
str = null;
sr = null;

Then in this case, what is the reachability of str? According the Java doc: An object is softly reachable if it is not strongly reachable but can be reached by traversing a soft reference. In the case, str can be reached by traversing wr and sr, which means the traversing goes through a soft reference. Can I say str is softly reachable? But following the section Chains of reference objects in this doc, it seems the str is weakly reachable.


Solution

  • For the reference to be softly reachable the soft reference itself must be either strongly reachable or softly reachable.

    You can think of these references as a chain: at one end is an anchor point (a garbage collection root: for example a reference in an active thread or a class field). At the other end is your object.

    The whole chain cannot be stronger than any of the elements in between, because the whole chain breaks as soon as any of the elements breaks and at that moment you loose the access to your object.

    The garbage collector clears weak references before it clears soft references and therefore weak references are weaker than soft references.

    That means with your example: as soon as the garbage collector clears the weak reference to the SoftReference object your object / string is inaccessible and will be garbage collected, even if the garbage collector does not yet clear the soft reference objects.