[concurrency-interest] Is Reference.reachabilityFence() needed in Reference constructor?
Vitaly Davidovich
vitalyd at gmail.com
Wed Oct 21 22:25:01 UTC 2015
>
> Yes, if runtime stripes that instance before it is exposed anywhere
> (e.g. scalarizes the weakref)
If you look at escape analysis code (
http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/file/a60bd3d34158/src/share/vm/opto/escape.cpp#l803),
Reference and subclasses get special treatment and marked as GlobalEscape.
On Wed, Oct 21, 2015 at 1:08 PM, Aleksey Shipilev <
aleksey.shipilev at oracle.com> wrote:
> On 10/21/2015 06:53 PM, Andrew Haley wrote:
> > On 10/21/2015 04:44 PM, Aleksey Shipilev wrote:
> >> Of course, this does not tell another (scary) part of the story, what if
> >> the Reference itself is not discovered as strong ref by GC, e.g. when it
> >> isn't published on heap, or scalarized by compiler, etc.
> >> reachabilityFence, as currently implemented, extends the "liveness"
> >> scope of the local variable, but does not convey anything special to the
> >> GC/runtime otherwise.
> >
> > If the Reference itself is not reachable from a strong root then the
> > Reference is dead so we don't care what happens to it. But if the
> > Reference is put on a reachable ReferenceQueue, then it's fine.
>
> Yes, if runtime stripes that instance before it is exposed anywhere
> (e.g. scalarizes the weakref), or those references are dead (e.g. the
> weakref is buried somewhere deep in garbage subgraph, and purged on
> sweep), then everything goes awry.
>
> But the thing is, a WeakReference is put on ReferenceQueue by the GC
> itself. In the object graph, ReferenceQueue does not normally reference
> weakrefs back. Before enqueueing the reference GC has to first discover
> that WeakReference -- but from where? In other words, "registering" on a
> reachable RefQueue does not make weakref to be reachable.
>
> Case in point:
>
> public class WhereIsWaldo {
>
> public static void main(String... args) throws Exception {
> for (int c = 0; true; c++) {
> new WhereIsWaldo().work(c);
> }
> }
>
> final ReferenceQueue<Object> rq = new ReferenceQueue<>();
>
> void work(int id) throws Exception {
> hideWaldo(id);
> findWaldo(id);
> }
>
> WeakReference<Object> gwr;
>
> void hideWaldo(int id) {
> // Does not work, d'uh
> new WeakReference<>(new Object(), rq);
>
> // Does not work either :(
> WeakReference<Object> wr =
> new WeakReference<>(new Object(), rq);
>
> // This also does not help... once you leave the method,
> // the weakref is gone.
> Reference.reachabilityFence(wr);
>
> // This one helps, makes Waldo reachable
> // gwr = wr;
> }
>
> void findWaldo(int id) throws Exception {
> while (Thread.currentThread().isAlive()) {
> System.gc();
> Reference ref = rq.remove(1000);
> if (ref != null) {
> return;
> } else {
> System.out.println("Where's Waldo #" + id + "?");
> }
> }
> }
> }
>
>
> Thanks,
> -Aleksey
>
>
More information about the core-libs-dev
mailing list