From paul.sandoz at oracle.com Tue Sep 2 14:42:36 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 2 Sep 2014 16:42:36 +0200 Subject: [jmm-dev] Non-core-model issues status In-Reply-To: <54032B87.4040703@cs.oswego.edu> References: <54032B87.4040703@cs.oswego.edu> Message-ID: On Aug 31, 2014, at 4:04 PM, Doug Lea
wrote: > 4. We will more uniformly support and spec analogs of C++/C11 moded > access on fields, array elements, and statics. I had initially > proposed doing this as a small syntactic extension in JEP193. But I > think everyone has now settled on instead introducing "VarHandles", > which are more language-agnostic; basically serving as lighter, more > broadly applicable, and more efficient variants of > AtomicXFieldUpdaters that exploit and extend JDK8 MethodHandles. Paul > Sandoz has been working on this within the Valhalla project, and has > committed a preliminary version (that I haven't used yet). (See > http://mail.openjdk.java.net/pipermail/valhalla-dev/2014-August/000111.html) > They are still not fully spec'ed, and probably cannot be until core > model settles. But given precedent in C++/C11, I don't expect major > obstacles in doing so. > The prototype can also support more efficient variants of AtomicXArray classes too, although there is more work to do done, for example to optimize away or strength reduced bounds checks. Paul. From boehm at acm.org Tue Sep 2 21:07:56 2014 From: boehm at acm.org (Hans Boehm) Date: Tue, 2 Sep 2014 14:07:56 -0700 Subject: [jmm-dev] Non-core-model issues status In-Reply-To: <54032B87.4040703@cs.oswego.edu> References: <54032B87.4040703@cs.oswego.edu> Message-ID: On Sun, Aug 31, 2014 at 7:04 AM, Doug Lea
wrote: > > By request, here's a summary of where I think we are on issues other > than reformulating the core model. None of these are final or > definitive, and new ideas are always welcome. > > ... > > 2. We introduce and spec a reachabilityFence(Object x) method, and add > wording about it in JLS sec 12.6. Further suggestions for doing more > are still welcome. (Also, the method name is still up for grabs. > Except that the name "keepAlive" is known to be too confusing > to consider.) I thought we were focusing primarily on an annotation to declare fields that are cleaned up by finalizers, so that accessing such fields inhibits elimination of "dead" references. I continue to believe that an API call by itself will not fix the problem. (One argument for keepAlive is that it's consistent with .NET: http://msdn.microsoft.com/en-us/library/system.gc.keepalive(v=vs.110).aspx . But I'm not longer convinced we really want such a primitive at all.) > > 3. I don't think we came to a consensus about guaranteeing > non-volatile 64bit (long, double) atomicity. There will still be 32bit > platforms without reasonable implementations around for years. But > even now they account for a tiny percentage of platforms. So even if > atomicity is not guaranteed, programmers may increasingly act as if it > were, because even high-quality software tests never fail in practice > unless run on uncommon processors. If this were C, we might add a > user-visible analog of JVM-internals that reveal whether a type is > atomic, and rely on programmers to use it. But I don't think we can > get away with this in Java. 32-bit MIPS seems to be the problem case here. It's unclear to me we can do this in good conscience, though this may be a good time to announce that we plan to eventually do it. Since this property will not hold for value types (or library calls with value-like behavior) or in other languages, I don't feel very strongly about it either way. I don't think it fundamentally simplifies programmer's lives. Presumably it would help some numerical algorithms that rely on racy updates, but that's not exactly Java's strength anyway. Hans From dl at cs.oswego.edu Sat Sep 6 12:04:54 2014 From: dl at cs.oswego.edu (Doug Lea) Date: Sat, 06 Sep 2014 08:04:54 -0400 Subject: [jmm-dev] Non-core-model issues status In-Reply-To: References: <54032B87.4040703@cs.oswego.edu> Message-ID: <540AF866.1000709@cs.oswego.edu> On 09/02/2014 05:07 PM, Hans Boehm wrote: > > 2. We introduce and spec a reachabilityFence(Object x) method, and add > > wording about it in JLS sec 12.6. Further suggestions for doing more > > are still welcome. (Also, the method name is still up for grabs. > > Except that the name "keepAlive" is known to be too confusing > > to consider.) > I thought we were focusing primarily on an annotation to declare fields that are > cleaned up by finalizers, so that accessing such fields inhibits elimination of > "dead" references. I continue to believe that an API call by itself will not > fix the problem. > Sorry for not being very consistent about this. The more I look into the practical problems people face using finalize, the less I believe that we can do anything that would lead anyone to ever recommend that people use it outside of a few niche contexts that already require lots of care and almost always involve synchronization patterns that avoid need for reachabilityFence/keepAlive. Still, reliance on coincidental properties of synchronize(x) seems like a too big of a flaw not to fix. See for example the core-libs-dev discussion going on among JDK and other library developers. Including: http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-September/028479.html and follow-ups. -Doug From boehm at acm.org Sun Sep 7 05:55:27 2014 From: boehm at acm.org (Hans Boehm) Date: Sat, 6 Sep 2014 22:55:27 -0700 Subject: [jmm-dev] Non-core-model issues status In-Reply-To: <540AF866.1000709@cs.oswego.edu> References: <54032B87.4040703@cs.oswego.edu> <540AF866.1000709@cs.oswego.edu> Message-ID: Doug - I don't really understand that claim. It seems to be quite common to use finalization in classes that encapsulate native objects, and use the Java object to deallocate the native one once the Java one becomes unreachable. There are reasons to use java.lang.ref instead of finalization to avoid some of the problems associated with the Java finalization design. But that's irrelevant to this discussion; java.lang.ref queues have the same issues, at least in the presence of more than one thread. Otherwise, I don't see a way around the use of finalizers/java.lang.ref queues in cases like this. And we seem to have lots of evidence that essentially everyone currently gets this code wrong, introducing premature deallocations. And I think this canonical application is usually correct, except for this issue. Based on a small random sample of our code base, this, and the relatively safe "warn if something leaked" idiom, are probably the dominant use case for finalizers. I agree that keepAlive would help, but all indications are that we would still be left with lots of broken code, because people just don't understand the problem. This solution could essentially remove the runtime cost associated with fixing the code, but the resulting code would still look very cluttered and ugly. I'm also concerned about ease of use for the annotation but, unlike keepAlive, it doesn't sound hopeless to me. It still seems to me it's worth exploring. In my opinion, a lot of the web discussion of finalizers, including the thread you cited, is badly flawed. Java finalizers (unlike Modula 3/Xerox Cedar finalizers) do have issues with ordering and the inability to finalize an object more than once. But those issues are largely fixed by java.lang.ref, or can be worked around with finalize(). I think the premature finalization issue we're talking about is the most serious problem we have in this area. Hans On Saturday, September 6, 2014, Doug Lea
wrote: > On 09/02/2014 05:07 PM, Hans Boehm wrote: > > > 2. We introduce and spec a reachabilityFence(Object x) method, and add >> > wording about it in JLS sec 12.6. Further suggestions for doing more >> > are still welcome. (Also, the method name is still up for grabs. >> > Except that the name "keepAlive" is known to be too confusing >> > to consider.) >> I thought we were focusing primarily on an annotation to declare fields >> that are >> cleaned up by finalizers, so that accessing such fields inhibits >> elimination of >> "dead" references. I continue to believe that an API call by itself will >> not >> fix the problem. >> >> > Sorry for not being very consistent about this. > The more I look into the practical problems people face using > finalize, the less I believe that we can do anything that would > lead anyone to ever recommend that people use it outside of a few > niche contexts that already require lots of care and almost > always involve synchronization patterns that avoid need for > reachabilityFence/keepAlive. Still, reliance on coincidental > properties of synchronize(x) seems like a too big of a flaw not > to fix. > > See for example the core-libs-dev discussion going on among > JDK and other library developers. Including: > http://mail.openjdk.java.net/pipermail/core-libs-dev/2014- > September/028479.html > and follow-ups. > > -Doug > > From aph at redhat.com Mon Sep 8 09:11:19 2014 From: aph at redhat.com (Andrew Haley) Date: Mon, 08 Sep 2014 10:11:19 +0100 Subject: [jmm-dev] Non-core-model issues status In-Reply-To: References: <54032B87.4040703@cs.oswego.edu> <540AF866.1000709@cs.oswego.edu> Message-ID: <540D72B7.70800@redhat.com> On 07/09/14 06:55, Hans Boehm wrote: > I think the > premature finalization issue we're talking about is the most serious > problem we have in this area. I don't think so. There is a related problem in that finalizers don't necessarily run. This is particularly so with generational collectors when an object is moved into the old generation, and the old generation isn't scanned until the heap runs very low. I have seen cases where the old generation is never scanned, and the system eventually runs out of native resources. This is true of the PKCS11 crypto provider. It is part of OpenJDK, and I have been unable to fix it despite working on it for some time. I have been thinking about a workaround: when a class is annotated as finalizable, modify the garbage collectors so that its instances are never placed in the old generation. My reasoning is that if a class is finalizable, it probably has some native resource that should be recycled, and it is best to do so as soon as possible. And this is "probably" cheaper than the cost of not moving this object to the old generation. But even though I believe this would solve some current problems, it's still not what I'd call "correct". Andrew. https://bugs.openjdk.java.net/browse/JDK-6913047 From boehm at acm.org Mon Sep 8 22:16:02 2014 From: boehm at acm.org (Hans Boehm) Date: Mon, 8 Sep 2014 15:16:02 -0700 Subject: [jmm-dev] Non-core-model issues status In-Reply-To: <540D72B7.70800@redhat.com> References: <54032B87.4040703@cs.oswego.edu> <540AF866.1000709@cs.oswego.edu> <540D72B7.70800@redhat.com> Message-ID: The other alternative is to run a sufficiently complete GC when you get low on "native" resources. Since we seem to be using the GC to manage more than just Java memory, triggering it only based on the Java heap looks more and more like an (admittedly universal) implementation misfeature to me. I think the solution that Andrew proposed doesn't quite work, particularly if the code uses "finalizer guardians", as is often recommended. The objects that refer to a finalizable object can still be promoted to the old generation, thus retaining the finalizable objects. But there exist implementation solutions, so I don't think this requires a spec change. Hans On Mon, Sep 8, 2014 at 2:11 AM, Andrew Haley wrote: > On 07/09/14 06:55, Hans Boehm wrote: > > I think the > > premature finalization issue we're talking about is the most serious > > problem we have in this area. > > I don't think so. There is a related problem in that finalizers don't > necessarily run. This is particularly so with generational collectors > when an object is moved into the old generation, and the old > generation isn't scanned until the heap runs very low. I have seen > cases where the old generation is never scanned, and the system > eventually runs out of native resources. > > This is true of the PKCS11 crypto provider. It is part of OpenJDK, > and I have been unable to fix it despite working on it for some time. > > I have been thinking about a workaround: when a class is annotated as > finalizable, modify the garbage collectors so that its instances are > never placed in the old generation. My reasoning is that if a class > is finalizable, it probably has some native resource that should be > recycled, and it is best to do so as soon as possible. And this is > "probably" cheaper than the cost of not moving this object to the old > generation. > > But even though I believe this would solve some current problems, it's > still not what I'd call "correct". > > Andrew. > > > https://bugs.openjdk.java.net/browse/JDK-6913047 > From dl at cs.oswego.edu Tue Sep 9 11:26:07 2014 From: dl at cs.oswego.edu (Doug Lea) Date: Tue, 09 Sep 2014 07:26:07 -0400 Subject: [jmm-dev] Non-core-model issues status In-Reply-To: References: <54032B87.4040703@cs.oswego.edu> <540AF866.1000709@cs.oswego.edu> Message-ID: <540EE3CF.5000008@cs.oswego.edu> On 09/07/2014 01:55 AM, Hans Boehm wrote: > we seem to have lots of evidence that essentially everyone currently gets > this code wrong, introducing premature deallocations. Continuing in vacillation mode.... What do you think of the following concrete version of Jeremy's original suggestion: 1. Introduce reachabilityFence (or whatever name; How about "keepReachable"?) 2. Spec at syntax level that every declaration and use of a local (or param) ref to an object of a class F defining finalize() is translated from: F f; ... to: F f; try { ... } finally if (f != null) reachabilityFence(f); } It might be a little challenging to spec this to cover multiple refs while keeping blocked scopes, but it seems feasible. This seems to completely address premature finalization, at the expense of lack of control in the other direction. The only middle ground I see is the one you like least, of telling people to write their own try-finally blocks. -Doug From boehm at acm.org Wed Sep 17 21:45:05 2014 From: boehm at acm.org (Hans Boehm) Date: Wed, 17 Sep 2014 14:45:05 -0700 Subject: [jmm-dev] Non-core-model issues status In-Reply-To: <540EE3CF.5000008@cs.oswego.edu> References: <54032B87.4040703@cs.oswego.edu> <540AF866.1000709@cs.oswego.edu> <540EE3CF.5000008@cs.oswego.edu> Message-ID: On Tue, Sep 9, 2014 at 4:26 AM, Doug Lea
wrote: > > On 09/07/2014 01:55 AM, Hans Boehm wrote: >> >> we seem to have lots of evidence that essentially everyone currently gets >> this code wrong, introducing premature deallocations. > > > Continuing in vacillation mode.... What do you think of > the following concrete version of Jeremy's original > suggestion: > > 1. Introduce reachabilityFence (or whatever name; > How about "keepReachable"?) > > 2. Spec at syntax level that every declaration and > use of a local (or param) ref to an object of a class F > defining finalize() is translated from: > F f; > ... > > to: > F f; > try { > ... > > } finally > if (f != null) reachabilityFence(f); > } > > It might be a little challenging to spec this to cover multiple > refs while keeping blocked scopes, but it seems feasible. I think that's similar to the earlier proposal with annotations, except that we're back to "defining finalize()" as the criterion for when to apply it. I think that's the wrong criterion. Counterexamples: - Any class that uses a finalizer guardian (recommended practice in places, I think) to perform finalization on its behalf. - Any object that's "finalized" by enqueuing it on a reference queue instead of using a "finalize()" method. (Recommended practice to deal with the lack of finalize() ordering.) I think we need a field annotation A that basically says: "This field becomes unusable once the enclosing object becomes unreachable". That's only loosely correlated with defining a finalize() method. We then essentially guarantee that every method that uses a field x.f, where f is annotated with A keeps x reachable as long as that would be expected by the naive semantics, by performing the transformation you suggest. I'm not sure, but I think we might be able to avoid dealing with transitive reachability issues. If field f is annotated with a, and I have T' x = ...; { T y = x.a; { foo(y.f); } } where x is finalizable with a finalizer that invalidates f, I should annotate both a and f, and the right things should happen. And that actually makes sense, I think. For things like new T'().a.foo(), where foo uses f, to work correctly, we probably need something like the C++ rule in the "naive semantics", that references stay around until the end of the enclosing full expression. This requires more thought, but this annotation seems to be significantly easier and cleaner to use than reachabilityFence. Hans > > This seems to completely address premature finalization, > at the expense of lack of control in the other direction. > > The only middle ground I see is the one you like least, > of telling people to write their own try-finally blocks. > > -Doug > > >