[gclist] A Java question.

John D. Mitchell johnm@non.net
25 Mar 1997 20:41:49 -0000

>>>>> "Charles" == Charles Fiterman <cef@geodesic.com> writes:
>>>>>> Mimir Reynisson <skelmir@qualia.com> writes:
>> All Java VM's must call finalizers and all as far as I know do.
>> finalize() is used to free up bitmaps, file references, and other
>> non-Java-related "garbage". I think you may be talking about the fact
>> that once a finalizer has been called once, it will not be called
>> again. So if you create a reference to the object being finalized in the
>> finalizer, you essentially create a zombie object and finalize() will
>> not be called the next time it tries to gc that object. Most of the time
>> this is not a problem.

Hmm...  The JLS (Java Language Specification) says "The Java language does
not specify how soon a finalizer will be invoked, except to say that it
will be happen before the storage for the object is reused."

It's also interesting to note that upon exit of the Java run-time, it is
*not* obliged to run finalize() on everything.  The Java v1.1 stuff
supposedly makes this configurable by using the
java.lang.System.runFinalizersOnExit() method but I haven't tried it.

It is Bad Practice(tm) to rely on finalization for reclaiming resources
which are heavily contended for (file handles) or otherwise where
timeliness is important (e.g., sockets).

> I have nothing against zombies but am worried about the zombie getting
> freed or any other pointer to a free object as those would allow me to
> create a virus. The point of Java is that the type system prevents the
> creation of viruses. There is also the question of finalizer order.

There was, IIRC, a lot of discussion about this in the Java newsgroups so
you probably want to check DejaNews.  Also, check the archives of the
advanced-java@xcf.berkeley.edu mailing list (as it has a higher
signal-to-noise ratio :-).

Note that there is the java.lang.System.runFinalization() and
java.lang.System.gc() methods (which are pretty much just a simple way to
invoke java.lang.Runtime.{runFinalization,gc}()) so you can "force" gc and
finalization.  Heck, you can even call finalizer methods directly.

The Java specification gives *no* guarantees about the relative ordering of
the calls to the various objects' finalize() method.

In terms of having access to freed resources via references that you are
holding which are accessible when a finalizer is invoked, check out the JLS
Section 12.6.1, page 232, "Implementing Finalization" for all sorts of
state-based discussion of Java finalization.  Basically, finalization and
freeing are separate "passes".

Hope this helps,