Java Reference
In-Depth Information
The
finalize()
method prints a message if the object being garbage collected has an
id
, which is a multiple of
100
.
The
main()
method creates 500,000 objects of the
Finalizer
class and calls
System.gc()
to invoke the garbage
collector.
When the garbage collector determines that an object is unreachable, it marks that object for finalization and
places that object in a queue. If you want the Java runtime to finalize all objects that are pending finalization, you can
do so by calling the
runFinalization()
method of the
Runtime
class as shown:
Runtime rt = Runtime.getRuntime();
rt.runFinalization();
The
System
class has a
runFinalization()
convenience method, which is equivalent to calling the
runFinalization()
method of the
Runtime
class. It can be called as shown:
System.runFinalization();
Invoking the
runFinalization()
method is only a hint to the Java runtime to invoke the
finalize()
method of
all objects pending finalization. Technically, you may call the
finalize()
method on an object in your code as many
times as you want. However, it is meant for the garbage collector to call an object's
finalize()
method at most one
time during the lifetime of the object. The garbage collector's one-time call to the
finalize()
method of an object is
not affected by the fact that the
finalize()
method of the object was called programmatically before.
Programmers should not override the
finalize()
method in a class trivially. A
finalize()
method with no code,
or which calls the
finalize()
method of the
Object
class, is an example of a trivially overridden
finalize()
method.
The method in the
Object
class does nothing. If your class is a direct subclass of the
Object
class and you do not have
any meaningful code in the
finalize()
method of your class, it is better not to include the
finalize()
method in
your class at all. Memory reclamation is faster and sooner for the objects, which do not have an implementation of the
finalize()
method compared to those that have an implementation of the
finalize()
method.
Finally or Finalize?
The time when an object is finalized is not guaranteed. Finalizing all unreachable objects is also not guaranteed.
In short, there is no guarantee when the
finalize()
method of an unreachable object will be called or if it will be
called at all. So, what good is the
finalize()
method? The main purpose of a garbage collector in Java is to relieve
programmers from the burden of freeing the memory of unused objects to avoid the problem of memory leaks and
dangling references. Its secondary job is to run the finalization on the objects with no guarantee about the timing.
As a programmer, you should not depend much on the finalization process of garbage collection. You should code the
finalize()
method with care. If you need to clean up resources for sure when you are done with them, you should
use a
try-finally
clause, such as
try {
/* Get your resources and work with them */
}
finally { /* Release your resources */
}
You can acquire resources and use them in a
try
block and release them in the associated
finally
block.
A
finally
block is guaranteed to be executed after a
try
block is executed. This way, you can be sure that scarce
resources in your program are always freed once you are done with them. However, it may not always be feasible,
because of performance issues, to release resources immediately after you are done with them. For example, you
may not want to open a network connection every time you need it. You may open a network connection once, use it,
and close it when you no longer need it. Sometimes you may not know the exact point in a program from where you