Java Reference
In-Depth Information
12.6.1. Implementing Finalization
Every object can be characterized by two attributes: it may be
reachable
,
finalizer-reach-
able
, or
unreachable
, and it may also be
unfinalized
,
finalizable
, or
finalized
.
A
reachable
object is any object that can be accessed in any potential continuing computa-
tion from any live thread.
A
finalizer-reachable
object can be reached from some finalizable object through some
chain of references, but not from any live thread.
An
unreachable
object cannot be reached by either means.
An
unfinalized
object has never had its finalizer automatically invoked.
A
finalized
object has had its finalizer automatically invoked.
A
finalizable
object has never had its finalizer automatically invoked, but the Java Virtual
Machine may eventually automatically invoke its finalizer.
An object
o
is not finalizable until its constructor has invoked the constructor for
Object
on
o
and that invocation has completed successfully (that is, without throwing an exception).
Every pre-finalization write to a field of an object must be visible to the finalization of
that object. Furthermore, none of the pre-finalization reads of fields of that object may see
writes that occur after finalization of that object is initiated.
Optimizing transformations of a program can be designed that reduce the number of objects
that are reachable to be less than those which would naively be considered reachable. For
example, a Java compiler or code generator may choose to set a variable or parameter that
will no longer be used to
null
to cause the storage for such an object to be potentially re-
claimable sooner.
Another example of this occurs if the values in an object's fields are stored in registers. The
program may then access the registers instead of the object, and never access the object
again. This would imply that the object is garbage. Note that this sort of optimization is
only allowed if references are on the stack, not stored in the heap.
For example, consider the
Finalizer Guardian
pattern:
class Foo {
private final Object finalizerGuardian = new Object() {
protected void finalize() throws Throwable {
/* finalize outer Foo object */