From the spec's point of view, all objects live forever. Garbage collection is just an optimization, permitted only because it is undetectable. Even though weak references are generally seen as making GC visible, we can actually specify weak references in a way that preserves the traditional approach: the spec will still assume all objects live forever, and will merely describe when it is permitted to remove certain edges to them.
An object is "relevant" if replacing it with any arbitrary other object could have a visible effect on the future execution of the program.
If there is a set of weak references such that none of their referent objects are relevant unless some weak reference within the set is followed, then it is permitted to cut all references in the set.
Suppose an object A
is pointed to by a weak reference B
, and by a variable.
Consider the set {B}
: A
is certainly relevant even if {B}
is never followed,
since A
can be used via the variable.
However, if the implementation can prove that the variable will never be used,
then A
can only be relevant if B
is dereferenced, and it is permitted to cut
all the references in {B}
(in other words, just B
itself).
Suppose two weak references R
and S
point to two objects O
and P
. Suppose further that the two objects point to each
other, but are not otherwise reachable.
-
Consider the set
{R}
. CertainlyO
is relevant even ifR
is not followed; it is reachable viaS
, and thenP
. It is not permitted to clearR
alone. -
Consider the set
{R, S}
.O
andP
are irrelevant unless some weak reference in{R, S}
is followed, so it is permitted to clearR
andS
simultaneously.
Suppose, in addition to O
, P
, R
, and S
, there is another object Q
reachable
only via a weak reference T
; Q
itself refers to nothing else. Consider the set
{R, S, T}
: none of their referent objects are relevant unless some weak
reference in that set is followed, so it is permitted to cut all three
together.