[concurrency-interest] [Javamemorymodel-discussion] Fences.keepAlive

Eger, Patrick peger at automotive.com
Tue Jan 20 18:08:06 EST 2009


Curious, why not either:

A)
Change the Java semantics to be more C++ like then? JVMs could simply
keep an extra object pointer on the method stack frame for "this" to
prevent GC so the implementation could likely be quite simple. Correct
finalization of the below datastructure would require synchronization of
some sort anyways, so the compiler/memory ordering barriers will already
likely be there preventing optimizations that could otherwise be made.
finalize()-free classes of course would not have any penalty at all
since the JIT could detect this. Importantly, I think the amount of code
that absolutely relies on GC to cleanup memory immediately (for
correctness) is little to non-existent. I may be off-base here but it
seems likely that more code would actually be fixed by this change than
broken. Dunno if this is acceptable or not.


Or alternatively, 

B)
Have the JIT implicitly insert a keepAlive(this) directly before the
method return, for all classes having a non-empty finalizer, in all
methods that access the "this" reference. This would have the advantage
of "fixing" these broken programs without possible breakage. The only
issue I can see here would be the possible performance impact.
Mitigating this i see a couple things: a) keepAlive(this) could be a
compiler intrinsic and so multiple keepAlive() "calls" could be
collapsed when inlining, etc. b) Coders have been warned against
finalize() strongly for so long that this would only effect those few
classes for which they are already expecting a performance hit.


Thoughts? Am I being naive here?


> -----Original Message-----
> From: concurrency-interest-bounces at cs.oswego.edu [mailto:concurrency-
> interest-bounces at cs.oswego.edu] On Behalf Of Boehm, Hans
> Sent: Tuesday, January 20, 2009 1:29 PM
> To: Alexander Terekhov
> Cc: Doug Lea; Concurrency-interest at cs.oswego.edu; javamemorymodel-
> discussion at cs.umd.edu
> Subject: Re: [concurrency-interest] [Javamemorymodel-discussion]
> Fences.keepAlive
> 
> > From: Alexander Terekhov [mailto:alexander.terekhov at gmail.com]
> >
> > On Tue, Jan 20, 2009 at 8:20 PM, Boehm, Hans
> > <hans.boehm at hp.com> wrote:
> > > I'd be inclined to somewhat simplify the example, and not use the
> > > constructor.  I'm also not sure I'd mention the word
> > "native", since
> > > that seems to mislead people to believe that this is a native code
> > > issue.  Something like:
> > >
> > > * class Resource {
> > > *   static Resource[] externalResourceArray = ...
> > > *   int myIndex;
> > > *   Resource(...) {
> > > *     myIndex = ...
> > > *     externalResourceArray[myIndex] = ...;
> > > *     ...
> > > *   }
> > > *   protected void finalize() {
> > > *     externalResourceArray[myIndex] = null;
> > > *     ...
> > > *   }
> > > *   void foo() {  // This might be the last use of this object.
> > > *      int i = myIndex;
> > > *      //  Without keepAlive, this object could be finalized
> > > *      //  here, and externalResoureArray[i] could be
> > > *      //  cleared, since the object itself may not otherwise
> > > *      //  be needed; if there are no later accesses, only
> > > *      //  the index i is still live.
> > > *      bar(externalResourceArray[i]);
> > > *      keepAlive(this);
> > > *   }
> > > * }
> >
> > Q: What does it mean to have no GC?
> > A: You must write "delete" (C++ locals aside for a moment) at
> > destruction point(s).
> >
> > Q: What does it mean to have a GC?
> > A: You must write "keepAlive" in every member function
> > possibly affected by the GC's premature destruction of *this.
> >
> The latter of course only applies to finalizable objects, of which
there
> should be very few.
> 
> The real difference between say, the C++ and Java approaches here is
> actually not so much the presence of GC.  C++ shared_ptr fundamentally
has
> the same issues, in some ways more so.  It seems to me that
interestingly
> the difference is that C++ effectively went for simpler semantics and
less
> performance here, while Java went for more performance at the expense
of
> programmability.  C++ delays destruction of locals until the end of
the
> block, thus prohibiting dead variable elimination where it might be
> visible.  Hence a shared_ptr and the like can't be destroyed early.
Java
> allows pointers to disappear early in ways that are visible to
finalizers.
> This makes at least some small amount of sense, since C++ destructors
are
> intended to be much more common that Java finalizers, and the
performance
> impact would still be more or less universal in Java.  Whether it is
> really the right decision for Java, I don't know.  But I think the
> decision was effectively (probably unintentionall!
>  y?) made around the Java 1.1 time frame, and changing it is likely to
be
> nontrivial.
> 
> Hans
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest



More information about the Concurrency-interest mailing list