Lightweight finalization for the JDK without any drawbacks was: Why is finalize wrong?

Doug Lea dl at cs.oswego.edu
Fri Aug 15 12:39:20 UTC 2014


Sorry for not answering this before you filed JDK-8055183.

On 08/13/2014 07:12 AM, Jaroslav Tulach wrote:
>
> As far as I understand Andrew's inquiry, the problem is not (that much)
> related to finalizers, rather to question whether following method can ever
> finish or not:
>
>      private void gcThis() {
>          Reference<?> ref = new WeakReference<>(this);
>          while (ref.get() != null) {
>              System.gc();
>          }
>          System.err.println("ref is gone: " + ref);
>      }
>
> On Oracle's JDK8 the method has never finished for me. However when I tried
> IBM's JDK (identification can be found below) the method finished every time! A
> bit of consistency would be beneficial in this area, imho.

I believe that either behavior is legal under current JLS specs.  See
in particular sec 12.6.2
(http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.6.2)
Among the few guaranteed ways to ensure that "this" is kept reachable
(and not GCable) is to write "this" somewhere after its fields are
used.  In other cases, a reference may or may not be kept reachable in
any given JVM, depending on safepoint schemes, whether the collector
is concurrent, etc.

The surprisingness of the rules, and the lack of any other means of
control have been known issues for years. Because reachability
interacts with other memory ordering rules (for example, just to
explain what "after" means above), we are discussing changes as part
of the JMM revisions. (See archives at
http://mail.openjdk.java.net/pipermail/jmm-dev/) These extend some
previous discussions and proposals that we never pushed through for
JDK7.

Minimally, there should be a means of forcing reachability without
forcing writes. One (old, unshipped) version of this can be found at
http://gee.cs.oswego.edu/dl/jsr166/dist/docs/java/util/concurrent/atomic/Fences.html

As first discovered by Hans Boehm, it just so happens that one way to
implement the equivalent of reachabilityFence(x) even now is
"synchronized(x) {}". (See Hans's 2005 JavaOne slides at
http://hboehm.info/misc_slides/java_finalizers.pdf) But I suspect that
a less weird and more efficient intrinsic will be introduced for JDK9.

Beyond this, we are discussing prospects for extending reachability
without programmers needing to use lots of reachabilityFences,
possibly by introducing an @Finalized annotation to automate common
cases.  I don't think there is consensus on this yet, in part because
there does not seem to be a way to do this that eliminates all
possible surprises/errors.

In the mean time, your RFE JDK-8055183
(https://bugs.openjdk.java.net/browse/JDK-8055183) seems to overlap
existing JMM revision efforts.  I don't know whether you'd like to
keep it open as a reminder, or just close it.

-Doug



More information about the core-libs-dev mailing list