is required in a few circumstances. In practice, it turns out to be a bad idea, and you should
try very hard not to use this method.
Finalizers are bad for functional reasons, and they are also bad for performance. Finalizers
are actually a special case of an indefinite reference: the JVM uses a private reference class
( java.lang.ref.Finalizer , which in turn is a java.lang.ref.FinalReference ) to keep
track of objects that have defined a finalize() method. When an object that has a final-
ize() method is allocated, the JVM allocates two objects: the object itself, and a Finalizer
reference that uses the object as its referent.
As with other indefinite references, it takes at least two GC cycles before the indefinite refer-
ence object can be freed. However, the penalty here is much greater than with other indefin-
ite reference types. When the referent of a soft or weak reference is eligible for GC, the refer-
ent itself is immediately freed; that leads to the memory use previously shown in Figure 7-9 .
The weak or soft reference is placed on the reference queue, but the reference object no
longer refers to anything (that is, its get() method returns null rather than the original ref-
erent). In the case of soft and weak references, the two-cycle penalty for GC applies only to
the reference object itself (and not the referent).
This is not the case for final references. The implementation of the Finalizer class must
have access to the referent in order to call the referent's finalize() method, so the referent
cannot be freed when the finalizer reference is placed on its reference queue. When the refer-
ent of a finalizer becomes eligible for collection, the program state is reflected by Fig-
ure 7-10 .