I have two questions:

1. Has there been any discussion of allowing WeakReference (and the corresponding JNI NewWeakGlobalRef) to accept value objects in a future revision of the value objects feature? Obviously in this case, the referent would never be cleared by GC, but it would allow common code to be able to continue to function. There are some "gotchas" here. For example, would such a reference ever be automatically enqueued on a ReferenceQueue? If so, when and how would that work?

Indeed, we have discussed this!  The first question is "what should the semantics of WR(value) be".  And there are actually at least three reasonable answers, and the choice of which is the "most right" is not as obvious as it might seem.

1.  As you suggest, WR(value) is just never cleared.
2.  A WR(value) is always immediately cleared.
3.  A WR(value) can be cleared only when any identities held within it are weakly reachable.

(1) is the first one everyone comes to, because it avoids cases like the one you've encountered -- but doesn't really implement any sort of weakness.  (2) is justifiable but likely useless in most cases. (3) is actually principled; it asks "could this value be reconstituted", and that is only true if its fields can be reconstituted, which is always true for pure values and true for identities if they are reachable.  But (3) is obviously very intrusive for the GC, and it is not obvious how helpful in practice it is.

Since there is not an obviously "right and useful and reasonably implementable answer", right now WRs just say "nope" when presented with a value object.

2. What is the best advice for applications or libraries like JavaFX to deal with this? The current approach we are considering is described in [2] and [3], where we would create a WeakReferenceWrapper class that either creates and stores a reference (if the object has identity) or stores the object itself (if it is either null or does not have identity). Its get method would return either ref.get() or obj. Is there a better approach?

This is what we recommend for the time being; it simulates semantics (1) above, but dumps the bookkeeping in your lap, which is obviously not great.

Longer-term, we observe that many of the uses of WR are through WeakHashMap, and it would be reasonable to specify a policy to the WHM constructor that says what to do: throw, follow (1), follow (2), etc.  A WRWrapper could then offer the same set of choices.  This would leave WR in its current, simple state.  I suspect there will never be one answer that does what all applications expect of WR(value), which is why a multiplicity of potential policies, implemented from outside of WR, seems likely.

Reply via email to