[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