SoV-2: weak references

Brian Goetz brian.goetz at oracle.com
Wed Jan 19 23:57:25 UTC 2022


It certainly seems that all the choices are bad.

The "obvious" choice is to simply say that WeakReference<Value> makes no 
sense, in that it sidesteps the hard semantics questions.  My fear is 
that this will cause new failures, where existing libraries that toss 
objects into WHMs to cache derived results, will start to experience new 
failures when the value types show up in the heap (after all, 
WeakReference::new takes Object.)  And we'll have to have something to 
tell those users, because they declared a WeakHashMap<User, UserData>, 
and someone created a value subtype of User -- which seems entirely valid.

It is possible we could do something special with WHM, since it is 
layered atop WR, but that still begs the question -- what?

On 1/19/2022 4:28 PM, Dan Heidinga wrote:
> In the Dec 2021 update to State of Valhalla, part 2: The language
> model, the section on "Identity-sensitive operations" states this
> about weak references:
>
>> Weak references to value objects that contain no references to identity objects should never be
>> cleared; weak references to value objects that contain references to identity objects should be
>> cleared when those objects are no longer strongly reachable.
> I'm concerned that this approach makes using weak references correctly
> for values very difficult, especially in the face of scalarization.
>
> Scalarization allows separating values into their individual
> components and flowing them separately through the code.  This can -
> with some caveats for decompilation and maybe other features - result
> in very different lifetimes for each separate component, with some
> object references going out of scope "earlier" than expected.  The
> source code will of course show the *entire* value being carried along
> even though only a single component may survive post-scalarization
> which means developers will see very different behaviour between the
> interpreter (which doesn't scalarize) and jitted code - making it very
> easy to write tests that give them the wrong impression.
>
> Reference::reachabilityFence was added in Java 9 to help users deal
> with premature finalization and has gotten little attention from most
> users. The proposed semantics for WeakReferences on value objects will
> drag the reachabilityFence method into the light and expose users to a
> problem they'd rather not have.  Just as we avoided exposing most
> users to tearing of their (bucket 2) value objects, we shouldn't
> expose them to having to reason about complicated reachability rules.
>
> Which is to say, Reference objects and value objects need to be
> incompatible to give users what they expect.  Anything else is loading
> a gun and pointing it at their feet.
>
> Here's an example of why the suggested rules for weak references using
> the identity objects may bring reachability issues to the forefront
> (where we don't want them):
>
> public value class ResourcePair {
>    static long nativePtr;
>    static IdentityObject companion;
>
>    ResourcePair(long ptr, IdentityObject o) {
>      nativePtr = ptr;
>      companion = o;
>    }
> }
>
> class PtrRef extends WeakReference<ResourcePair> {
>    long nativePtr;
>
>    PtrRef(ResourcePair p, ReferenceQueue q) {
>      super(p, q);
>      nativePtr = p.nativePtr;
>    }
>
>    void free() { /* do something to nativePtr */ }
> }
>
> If the `companion` object of the ResourcePair value goes out of scope
> before `nativePtr` is done being used - the issue of reachabilityFence
> - the ReferenceQueue processor could call free() before the
> `nativePtr` is done being used.  Scalarization will make this more
> common and even very common if we're getting the benefits we expect
> from it.
>
> --Dan
>


More information about the valhalla-spec-observers mailing list