The Artima Developer Community
Sponsored Link

Cleaning Up After Jini Services
Standardize the Way Jini Clients Release Resources
by Bill Venners
First Published in JavaWorld, March 2000

<<  Page 3 of 8  >>


When to use finalizers
In my Design Techniques article, I concluded that finalizers are useful only rarely, but I gave a few examples of when finalizers did make sense:

One reasonable, though rare, application for a finalizer is to free memory allocated by native methods. If an object invokes a native method that allocates memory (perhaps a C function that calls malloc()), that object's finalizer could invoke a native method that frees that memory (calls free()). In this situation, you would be using the finalizer to free up memory allocated on behalf of an object -- memory that will not be automatically reclaimed by the garbage collector.

Another, more common, use of finalizers is to provide a fallback mechanism for releasing finite nonmemory resources such as file handles or sockets. As mentioned previously, you shouldn't rely on finalizers for releasing finite nonmemory resources. Instead, you should provide a method that will release the resource. But you may also wish to include a finalizer that checks to make sure the resource has already been released, and if it hasn't, that goes ahead and releases it. Such a finalizer guards against (and hopefully will not encourage) sloppy use of your class. If a client programmer forgets to invoke the method you provided to release the resource, the finalizer will release the resource if the object is ever garbage collected. The finalize() method of the LogFileManager class, shown later in this article, is an example of this kind of finalizer.

The "Finalizable Object" idiom
After ending my Design Techniques column in early 1999, I began to organize the column material into a book called The Precise Object. This book, which I am still in the process of writing, will include 10 Java object idioms. In organizing the material, I decided that using a finalizer to perform the cleanup neglected by the client code was important enough to mention as an idiom in the book. I call this idiom the "Finalizable Object" idiom.

Any class containing one or more methods that can grab a finite nonmemory resource, which isn't released before the method returns, should be finalizable. Here's the recipe for the Finalizable Object idiom:

Testing "final conditions"
On a few occasions I've presented The Precise Object material in a workshop with Bruce Eckel. In the workshop, which I call the "Object Design Workshop," I present a guideline or idiom, then lead a discussion about it, so that participants can share their experiences and opinions and learn from one another.

Last summer, Bruce and I gave our first iteration of this workshop in Crested Butte, Colorado. During the Finalizable Object idiom discussion, Bruce expressed concern that if someone defines a finalizer that does clean up, then client programmers might become lazy about calling the cleanup method. He was worried that programmers would see the finalizer and think, "I don't need to invoke close() (or whatever the cleanup method is called), because the finalizer will invoke close() for me." Such laziness would be dangerous because the program would depend on timely finalization for correctness. Given such a dependency, the application could potentially run out of file handles on some virtual machine implementations.

Bruce and I realized that such a finalizer could detect a programming bug, which I subsequently started calling an unmet "final condition." The semantics of a finalizable object should state that clients must put the finalizable object into a "cleaned up" state, by invoking the cleanup method or methods on the object, before the client releases all references to the object.

Thus, if a finalizable object's finalizer detects that the client didn't call the cleanup method before releasing all references to the object, the finalizer has detected an unmet final condition. In effect, it has detected a programming error, because the client didn't use the object correctly, as defined by the semantics of the object's class.

Bruce and I also realized that a final condition is similar to the pre-conditions, post-conditions, and invariants of Bertrand Meyer's "Design by Contract" approach to programming (Resources). Just as unmet preconditions, postconditions, and invariants can usually be reported, we discussed that perhaps a finalizer could actually report an unmet final condition in some way, such as with an assert or a message in an error log. Bruce felt that the finalizer shouldn't fix the problem by calling the cleanup method, but should just report the problem. I continued to believe in the importance of my Finalizable Object idiom, which states that a finalizer should perform any cleanup the program neglected to perform. But nevertheless, in my discussion of the idiom I raise the possibility of reporting unmet final conditions, in addition to performing the cleanup.

<<  Page 3 of 8  >>

Sponsored Links

Copyright © 1996-2018 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use