...
The caveats associated with the usage use of finalizers are discussed here:
...
Wiki Markup According to the Java Language Specification: \[[JLS 05|AA. Java References#JLS 05]\] Section 12.6.2:
Wiki Markup The Java programming language imposes no ordering on finalize method calls. Finalizers \[of different objects\] may be called in any order, or even concurrently.
- Effect of uncaught exceptions: An uncaught exception thrown during finalization is ignored. The finalization process itself stops immediately so it fails to accomplish its purpose.
...
- A possibility exists such that the programmer unintentionally resurrects the references in the
finalize
method. While the garbage collector must determine yet again whether the object is free to be deallocated, thefinalize
method is not invoked again.
- A superclass can use finalizers and pass some additional overhead to extending classes. An example from JDK 1.5 and earlier demonstrates this. The code snippet below allocates a 16 MB buffer for backing a Swing
Jframe
. None of theJFrame
APIs have afinalize
method, however,JFrame
extendsAWT Frame
which has afinalize
method. The byte buffer continues to persist until thefinalize
method gets called and lasts for at least two garbage collection cycles.
Code Block |
---|
Class MyFrame extends Jframe {
private byte[] buffer = new byte[16 * 1024 * 1024]; // persists for at least two GC cycles
}
|
- It is also imprudent to use finalizers for reclaiming scarce resources by inviting garbage collection. Garbage collection usually depends on memory related traits and not on the scarcity of a particular resource. Thus, if memory is available aplenty, there is no reason for the scarce resource to not get exhausted despite the use of a finalizer. See FIO34-J. Ensure all resources are properly closed when they are no longer needed and CON02-J. Facilitate thread reuse by using Thread Pools for more on handling resources correctly.
Exceptions
OBJ02-EX1: Sometimes it is necessary to use finalizers especially while working with native objects/code. This is because the garbage collector cannot re-claim memory from code written in another language. Again, the native process must not perform any critical jobs that require immediate resource deallocation.
...
Code Block |
---|
public class Foo { // The finalizeGuardian object finalizes the outer Foo object private final Object finalizerGuardian = new Object() { protected void finalize() throws Throwable { // Finalize outer Foo object } }; //... } |
If a superclass defines a finalize
method, make sure to decouple the objects that can be immediately garbage collected from those that depend on the finalizer. In the MyFrame
example, the following code will ensure that the buffer
doesn't persist longer than expected.
Code Block |
---|
Class MyFrame {
private JFrame frame;
private byte[] buffer = new byte[16 * 1024 * 1024]; // now decoupled
}
|
Risk Assessment
Finalizers can have unexpected behavior.
...
Wiki Markup |
---|
\[[JLS 05|AA. Java References#JLS 05]\] Section 12.6, Finalization of Class Instances
\[[API 06|AA. Java References#API 06]\] [finalize()|http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#finalize()]
\[[Bloch 08|AA. Java References#Bloch 08]\] Item 7, Avoid finalizers
\[[Darwin 04|AA. Java References#Darwin 04]\] Section 9.5, The Finalize Method
\[[Flanagan 05|AA. Java References#Flanagan 05]\] Section 3.3, Destroying and Finalizing Objects
\[[Coomes 07|AA. Java References#Coomes 07]\] "Sneaky" Memory Retention |
...
OBJ01-J. Understand how a superclass can affect a subclass 06. Object Orientation (OBJ) OBJ03-J. Be careful about final reference