Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added discussion

...

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, the finalize 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 the JFrame APIs have a finalize method, however, JFrame extends AWT Frame which has a finalize method. The byte buffer continues to persist until the finalize 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 
}

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