[jmm-dev] finalization

Doug Lea dl at cs.oswego.edu
Sat Aug 16 14:16:30 UTC 2014


On 08/15/2014 11:46 AM, Paul Benedict wrote:
> I wonder if @Finalized should come with an option that specifies the kind of
> guarantee/behavior needed? This way no one is shoe-horned into a single solution.
>
> @Finalized(mode=)
>

I don't offhand see how modes on @Finalized could work here.
But it might be worth exploring somehow specifically supporting
the few known categories of classes defensibly implementing
finalize(), with potentially @Finalized fields of form:

1. Closeable/AutoCloseable objects; typically entailing release of native
resource handles. (Some have close-like methods not named "close".)
Finalization avoids users needing to manually emulate reference
counting to track the last use.

2. Native pointers (or offsets) to memory that is freed after last use.
These cases usually differ from (1) in that early reclamation leads
to crashes or corruption rather than exceptions.

3. Keys enabling bookkeeping data structure cleanup, as in removing
record of an object in a table. Usually, the main goal here is to
prevent long-term memory retention/leaks in a global data structure.

4. Heuristic early reclamation.

We've seen examples posted of the first three. The only
usage of finalize() in java.util.concurrent, class
ThreadPoolExecutor (TPE) is an example of the fourth.
It invokes shutdown() just to be helpful about triggering early
resource reclamation of possibly many Threads. But users cannot
rely on TPEs being auto-shutdown in a way that overcomes the JVM
rule that main programs cannot terminate until all other non-daemon
threads terminate, so must in general call tpe.shutdown() before
exit. Some not-very-relevant further notes for the curious:
  * The other j.u.c thread pool, ForkJoinPool uses daemon threads,
    and not finalize(), but also kills off threads internally
    after periods of non-use.  When available, this is a better
    option for dealing with the JVM shutdown rule.
  * Because of internal synchronization within TPE methods,
    there's no risk of premature shutdown even without reachability
    fences.
  * There are actually two cases of finalize in j.u.c. The second
    is just an internal j.u.c.Executors class that delegates to TPE.

Also, while I'm at it...

> On Fri, Aug 15, 2014 at 10:19 AM, Doug Lea <dl at cs.oswego.edu
> <mailto:dl at cs.oswego.edu>> wrote:
>
>     Short of requiring full dataflow analysis tracing all dependencies of the
>     resource field read, the safest and probably easiest policy seems to be
>     to insert upon method exit. But in some cases this would retain
>     enough garbage that some programmers would want to manually override.

Deja vu. Discussion of this years ago led us to add
a Javadoc example in the never-shipped Fences version
recommending explicit scope control via try/finally:
(http://gee.cs.oswego.edu/dl/jsr166/dist/docs/java/util/concurrent/atomic/Fences.html)

public void action() {
      try {
        // ...
        int i = myIndex;
        Resource.update(externalResourceArray[i]);
      } finally {
        Fences.reachabilityFence(this);
      }
    }

It is now also possible to illustrate an alternative version
with a method taking a lambda for the body and performing it
within such a try/finally.

-Doug





More information about the jmm-dev mailing list