Ephemerons
Peter Levart
peter.levart at gmail.com
Sat Jan 23 13:14:28 UTC 2016
Hi Gil, it's good to have this discussion. See comments inline...
On 01/23/2016 05:13 AM, Gil Tene wrote:
....
>> On Jan 22, 2016, at 2:49 PM, Peter Levart <peter.levart at gmail.com
>> <mailto:peter.levart at gmail.com>> wrote:
>>
>> Ephemeron always touches definitions of at least two consecutive
>> strengths of reachabilities. The prototype says:
>>
>> * <li> An object is <em>weakly reachable</em> if it is neither
>> * strongly nor softly reachable but can be reached by traversing a
>> * weak reference or by traversing an ephemeron through it's value while
>> * the ephemeron's key is at least weakly reachable.
>>
>> * <li> An object is <em>ephemerally reachable</em> if it is neither
>> * strongly, softly nor weakly reachable but can be reached by
>> traversing an
>> * ephemeron through it's key or by traversing an ephemeron through
>> it's value
>> * while it's key is at most ephemerally reachable. When the
>> ephemerons that
>> * refer to ephemerally reachable key object are cleared, the key
>> object becomes
>> * eligible for finalization.
>
> Looking into this a bit more, I don't think the above is quite right.
> Specifically, If an ephemeron's key is either strongly of softly
> reachable, you want the value to remain appropriately strongly/softly
> reachable. Without this quality, Ephemeron value referents can (and
> will) be prematurely collected and finalized while the keys are not.
> This (IMO) needed quality not provided by the behavior you specify…
This is not quite true. While ephemeron's value is weakly or even
ephemerally-reachable, it is not finalizable, because
ephemeraly-reachable is stronger than finaly-reachable. After
ephemeron's key becomes ephemeraly-reachable, the ephemeron is cleared
by GC which sets it's key *and* value to null atomically. The life of
key and value at that moment becomes untangled. Either of them can have
a finalizer or not and both of them will eventually be collected if not
revived by their finalize() methods. But it can never happen that
ephemeron's value is finalized or collected while it's key is still
reachable through the ephemeron (while the ephemeron is not cleared yet).
But I agree that it would be desirable for ephemeron's value to follow
the reachability of it's key. In above specification, if the key is
strongly reachable, the value is weakly reachable, so any WeakReferences
or SoftReferences pointing at the Ephemeron's value can already be
cleared while the key is still strongly reachable. This is arguably no
different than current specification of Soft vs. Weak references. A
SoftReference can already be cleared while its referent is still
reachable through a WeakReference, but for Ephemeron's value this might
be confusing. The easier to understand conceptual model for Ephemerons
might be a pair of (WeakReference<K>, WeakReference<V>) where the key
has a virtual strong reference to the value. And this is what we get if
we say that reachability of the value follows reachability of the key.
>
> For a correctly specified behavior, I think all strengths (from strong
> down) need to be affected by key/value Ephemeron relationships, but
> without adding an "ephemerally reachable" strength. E.g. I think you
> fundamentally need something like this:
>
> - "An object is <em>strongly reachable</em> if it can be reached by
> (a) some thread without traversing any reference objects, or by (b)
> 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 <em>softly reachable</em> if it is not
> strongly reachable but can be reached by (a) traversing a soft
> reference or by (b) traversing the value of an Ephemeron whose key is
> softly reachable.
>
> - "An object is <em>weakly reachable</em> if it is neither strongly
> nor softly reachable but can be reached by (a) traversing a weak
> reference or by (b) traversing the value of an ephemeron whose key is
> weakly reachable.
...and that's where we stop, because when we make Ephemeron just a
special kind of WeakReference, the next thing that happens is:
* <p> Suppose that the garbage collector determines at a certain point
in time
* that an object is <a href="package-summary.html#reachability">weakly
* reachable</a>. At that time it will atomically clear all weak
references to
* that object and all weak references to any other weakly-reachable
objects
* from which that object is reachable through a chain of strong and soft
* references. At the same time it will declare all of the formerly
* weakly-reachable objects to be finalizable. At the same time or at some
* later time it will enqueue those newly-cleared weak references that are
* registered with reference queues.
...where "clearing of the WeakReference" means reseting the key *and*
value to null in case it is an Ephemeron; and
"all weak references to some object" means Ephemerons that have that
object as a key (but not those that only have it as a value!) in case of
ephemerons
...
> I still think that Ephemeron<K, V> should extend WeakReference<K>,
> since that places already established rules and expectation on (a)
> when it will be enqueued, (b) when the collector will clear it (when
> the the collector encounters the <K> key being weakly reachable), and
> (c) that clearing of all Ephemeron *and* WeakReference instances who
> share an identical key value is done atomically, along with (d) all
> weak references to to any other weakly-reachable objects from which
> that object is reachable through a chain of strong and soft
> references. These last (c, d) parts are critically captured since an
> Ephemeron *is a* WeakReference, and the statement in WeakReference
> that says that "… it will atomically clear all weak references to that
> object and all weak references to any other weakly-reachable objects
> from which that object is reachable through a chain of strong and soft
> references." has a clear application.
>
> Here are some suggested edits to the JavaDoc to go with this suggested
> spec'ed behavior:
> /**
> * Ephemeron<K, V> objects are a special kind of WeakReference<K>
> objects, which
> * hold two referents (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<K>, 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:
> * (a) strongly reachable if the key referent of the same Ephemeron
> * object is strongly reachable, or if the value referent is
> otherwise strongly reachable.
> * (b) softly reachable if it is not strongly reachable, and (i) the
> key referent of
> * the same Ephemeron object is softly reachable, or (ii) if the
> value referent is otherwise
> * softly reachable.
> * (c) weakly reachable if it is not strongly or softly reachable,
> and (i) the key referent of
> * the same Ephemeron object is weakly reachable, or (ii) if the
> value referent is otherwise
> * weakly reachable.
> * <p> When the collector clears an Ephemeron object instance
> (according to the rules
> * expressed for clearing WeakReference object instances), the
> Ephemeron instance's
> * key referent value referent are simultaneously and atomically cleared.
> * <p> By convenience, the Ephemeron's referent is also called the
> key, and can be
> * obtained either by invoking {@link #get} or {@link #getKey} while
> the value
> * can be obtained by invoking {@link #getValue} method.
> *...
Thanks, this is very nice. I do like this behavior more.
Let me see what it takes to implement this strategy...
Regards, Peter
More information about the core-libs-dev
mailing list