|
|
|
Sponsored Link •
|
|
Advertisement
|
Managing non-memory resources
Because heap memory is automatically reclaimed by the garbage
collector, the main thing you need to worry about when you design an
object's end-of-lifetime behavior is to ensure that finite non-memory
resources, such as file handles or sockets, are released. You can take
any of three basic approaches when you design an object that needs to
use a finite non-memory resource:
Approach 1: Obtain and release within each relevant method
As a general rule, the releasing of non-memory finite resources should
be done as soon as possible after their use because the resources are,
by definition, finite. If possible, you should try to obtain a
resource, use it, then release it all within the method that needs the
resource.
A log file class: An example of Approach 1
An example of a class where Approach 1 might make sense is a log file
class. Such a class takes care of formatting and writing log messages
to a file. The name of the log file is passed to the object as it is
instantiated. To write a message to the log file, a client invokes a
method in the log file class, passing the message as a
String. Here's an example:
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.IOException;
class LogFile {
private String fileName;
LogFile(String fileName) {
this.fileName = fileName;
}
// The writeToFile() method will catch any IOException
// so that clients aren't forced to catch IOException
// everywhere they write to the log file. For now,
// just fail silently. In the future, could put
// up an informative non-modal dialog box that indicates
// a logging error occurred. - bv 4/15/98
void writeToFile(String message) {
FileOutputStream fos = null;
PrintWriter pw = null;
try {
fos = new FileOutputStream(fileName, true);
try {
pw = new PrintWriter(fos, false);
pw.println("------------------");
pw.println(message);
pw.println();
}
finally {
if (pw != null) {
pw.close();
}
}
}
catch (IOException e) {
}
finally {
if (fos != null) {
try {
fos.close();
}
catch (IOException e) {
}
}
}
}
}
Class LogFile is a simple example of Approach 1. A more
production-ready LogFile class might do things such as:
The main feature of this simple version of class LogFile
is that it surrounds each log message with a series of dashes and a
blank line.
Using finally to ensure resource release
Note that in the writeToFile() method, the releasing of
the resource is done in finally clauses. This is to make sure the
finite resource (file handle) is actually released no matter how the
code is exited. If an IOException is thrown, the file will
be closed.
Pros and cons of Approach 1
The approach to resource management taken by class LogFile
(Approach 1 from the above list) helps make your class easy to use,
because client programmers don't have to worry about explicitly
obtaining or releasing the resource. In both Approach 2 and 3 from the list above
client programmers must remember to explicitly invoke a
method to release the resource. In addition -- and what can be far more
difficult -- client programmers must figure out when their programs no
longer need a resource.
A problem with Approach 1 is that obtaining and releasing the
resource each time you need it may be too inefficient. Another problem
is that, in some situations, you may need to hold onto the resource
between invocations of methods that use the resource (such as
writeToFile()), so no other object can have access to it.
In such cases, one of the other two approaches is preferable.
|
Sponsored Links
|