JDK-8172476 : ephemerons (weak references for reference tuples)
  • Type: New Feature
  • Component: core-libs
  • Sub-Component: java.lang
  • Priority: P4
  • Status: New
  • Resolution: Unresolved
  • Fix Versions: tbd_major
  • Submitted: 2017-01-10
  • Updated: 2021-03-06
Related Reports
Relates :  
Relates :  
Relates :  
Description
See this thread from Peter Levart on core-libs-dev:
http://mail.openjdk.java.net/pipermail/core-libs-dev/2016-January/038256.html

POC:
http://cr.openjdk.java.net/~plevart/misc/Ephemeron/webrev.jdk.02/
http://cr.openjdk.java.net/~plevart/misc/Ephemeron/webrev.hotspot.02/

Reference:
https://static.aminer.org/pdf/PDF/000/522/273/ephemerons_a_new_finalization_mechanism.pdf

Ripped javadoc from webrev.jdk.02:

`Ephemeron` objects are a special kind of `WeakReference` objects, which
hold two referents (a normal referent, also called a key referent, and a
value referent) and do not prevent their referents from being made
finalizable, finalized, and then reclaimed. In addition to the key
referent, which adheres to the referent behavior of a `WeakReference`,
an ephemeron also holds a value referent whose reachabiliy strength is
affected by the reachability strength of the key referent. The value
referent of an Ephemeron instance is considered:

-   *strongly reachable* if the key referent of the same Ephemeron
    object is strongly reachable, or if the value referent is otherwise
    strongly reachable.
-   *softly reachable* if it is not strongly reachable, and the key
    referent of the same Ephemeron object is softly reachable, or if the
    value referent is otherwise softly reachable.
-   *weakly reachable* if it is neither strongly nor softly reachable,
    and the key referent of the same Ephemeron object is weakly
    reachable, or if the value referent is otherwise weakly reachable.

When the collector clears an Ephemeron object instance (according to the
rules expressed for clearing WeakReference object instances), the
Ephemeron instance's key referent and value referent are simultaneously
and atomically cleared.

By convenience, the Ephemeron's normal referent is also called the key
referent, and can be obtained either by invoking [`#get`] or [`#getKey`]
while the value referent can be obtained by invoking [`#getValue`]
method.

### Reachability (should be moved to package-level docs)

Going from strongest to weakest, the different levels of reachability
reflect the life cycle of an object. They are operationally defined as
follows:

-   An object is *strongly reachable* if it can be reached by some
    thread without traversing any reference objects, or by traversing
    the value of an Ephemeron whose key is strongly reachable. A
    newly-created object is strongly reachable by the thread that
    created it
-   An object is *softly reachable* if it is not strongly reachable but
    can be reached by traversing a soft reference or by traversing the
    value of an Ephemeron whose key is softly reachable.
-   An object is *weakly reachable* if it is neither strongly nor softly
    reachable but can be reached by traversing a weak reference or by
    traversing the value of an ephemeron whose key is weakly reachable.
    When the weak references to a weakly-reachable object are cleared,
    the object becomes eligible for finalization.
-   An object is *phantom reachable* if it is neither strongly, softly,
    nor weakly reachable, it has been finalized, and some phantom
    reference refers to it.
-   Finally, an object is *unreachable*, and therefore eligible for
    reclamation, when it is not reachable in any of the above ways.

Comments
I'd just like to say I'd have a very concrete use case for ephemerons in Dyanlink (which could be used by a bunch of other dynamically linking solutions too), namely using them to link method handles in call sites conditionally in such a manner that the call site doesn't prevent the class hosting the method being linked to from getting garbage collected. That way call sites could do guardWithTest-style linkage of "if callee instanceof X, then invoke ((X)callee).foo()", and if X class would otherwise become unreachable, then this linkage would not keep it pinned in memory. This'd make linking memory leak safe when the class where the linked invokedynamic site is is linked to a method in a class that isn't in the same or ancestor class loader with it.
06-03-2021

Ephemerons have also been discussed from time to time on Doug Lea's concurrency-interest list over the years. Seems to be one of those things that can never quite get enough traction to move forward.
16-01-2017