Java 101: Trash talk, Part 1

Java recycles its memory through garbage collection

1 2 3 4 5 Page 5
Page 5 of 5

FinalizeDemo3 introduces a loop that repeatedly creates an object and assigns that object's reference to the same object reference variable. As an object's reference replaces a previously created object's reference, the previously created object becomes unreachable. At various points during the program's execution, the garbage collector runs some of the unreachable objects' finalize() methods. It then collects those objects.

The previous paragraph implies that not all finalize() methods for all unreachable objects run before a program exits. If you strive to have the garbage collector run the finalize() methods for all unreachable objects (such as FinalizeDemo3 objects), try placing the following two method calls at the end of the main() method:

System.gc ();
System.runFinalization ();

According to the SDK documentation, following the System.gc (); method call, System.runFinalization (); :

... suggests that the Java Virtual Machine expend effort toward running the finalize methods of objects that have been found to be discarded but whose finalize methods have not yet been run. When control returns from the method call, the Java Virtual Machine has made a best effort to complete all outstanding finalizations.

Does that work? On my platform, running the modified FinalizeDemo3 shows that, for every constructor call, there is a matching finalize() call. As a result, the answer -- for me, and most likely for you -- is yes.

Caution
You should call System.runFinalization (); immediately after the call to System.gc ();. If you place System.runFinalization (); before System.gc (); or omit the System.gc (); call, not all finalize() methods will run. (I do not know the reason for this.)

Resurrection

You would think that after an object's finalize() method runs, the garbage collector would always collect that object. However, this is not always true. Within a finalize() method, you can assign the dying object's reference to a reference variable and prevent that object's collection, an act many developers call resurrection. Listing 4 demonstrates resurrection:

Listing 4. Resurrection.java

// Resurrection.java
class Resurrection
{
   static Resurrection r;
   public static void main (String [] args)
   {
      new Resurrection ().hello ();
      System.gc ();
      r.hello ();
      r = null;
      System.gc ();
   }
   void hello ()
   {
      System.out.println ("hello");
   }
   public void finalize () throws Throwable
   {
      System.out.println ("finalize() called");
      super.finalize ();
      r = this;
   }
}

Resurrection creates a Resurrection object, calls that object's hello() method, and promptly discards its object reference. Then it asks the JVM to run the garbage collector. On my platform, the garbage collector usually runs. However, there is no guarantee that it will run on your platform. If it fails to run, the subsequent r.hello (); method call throws a NullPointerException object because r contains null. But if the garbage collector does run, r contains a reference to the resurrected object (after finalize() runs), and the hello method executes. Subsequently, null assigns to r, and the JVM makes a second attempt to run the garbage collector. On my platform, that attempt shows that finalize() is not called a second time. Assuming that everything works, you should see the following output; if not, try running the program a few times in a row:

hello
finalize() called
hello

Developers typically use resurrection to maintain a pool of commonly used objects. However, resurrection can obscure source code and confuse what that code tries to accomplish. Therefore, instead of using resurrection, you should examine other techniques, such as cloning and the Reference API. We'll explore the Reference API in Part 2 of this series.

Caution
If you resurrect an object and then make that object unreachable, the next time the garbage collector runs, it will collect that object without calling the object's finalize() method.

Review

As a Java program runs, unreferenced objects accumulate on the object heap. The JVM's garbage collector automatically recycles unreferenced objects' memory each time it runs. Java's System class supplies a gc() method that you can call to ask the JVM to run the garbage collector. Your code should typically call that method before entering a long-running sequence of calculations that results in the allocation of much heap memory.

Many objects have overridden finalize() methods that the garbage collector calls prior to collecting those objects. Code within that method typically releases any finite resources held by the object. However, an object can also resurrect itself in its finalize() method. That happens when code within finalize() assigns the current object's reference to some root-set reference variable. Although tempting, resurrection is not a good idea because it can lead to complex code.

I strongly encourage you to review the various resources on garbage collecting as they expand on this article's concepts. Without that additional knowledge, you might be left wondering why certain things work the way they do.

I also encourage you to email me with any questions you might have involving either this or any previous article's material. (Please, keep such questions relevant to material discussed in this column's articles.) Your questions and my answers will appear in the relevant study guides.

Jeff Friesen has been involved with computers for the past 20 years. He holds a degree in computer science and has worked with many computer languages. Jeff has also taught introductory Java programming at the college level. In addition to writing for JavaWorld, he has written his own Java book for beginners -- Java 2 By Example, Second Edition (Que Publishing, 2001; ISBN: 0789722666) -- and helped write Special Edition Using Java 2 Platform (Que Publishing, 2001; ISBN: 0789720183). Jeff goes by the nickname Java Jeff (or JavaJeff). To see what he's working on, check out his Website at http://www.javajeff.com.

Learn more about this topic

1 2 3 4 5 Page 5
Page 5 of 5