Section
3 : Garbage Collection
State the behavior that is guaranteed by the
garbage collection system, and write code that
explicitly makes objects eligible for collection.
Java, they say, scores
over other languages like C or C++ in memory
management. In Java you need not worry about memory
management since its garbage collection mechanism
takes care of memory leaks. When an object cannot be
referenced in a program or if it cannot be accessed
anymore, maybe due to its reference being assigned to
another object or its reference being set to null, it
becomes eligible for garbage collection. The built in
garbage collector mechanism then reclaims the memory
which had been allocated to the object.
The storage allocated to an object is not recovered
unless it is definitely no longer in use. Even though
you may not be using an object any longer, you cannot
say when, even if at all, it will be collected. Even methods like
System.gc() and Runtime.gc() cannot be relied upon in
general, since some other thread might prevent the
garbage collection thread from running.
An important
consequence of the nature of automatic garbage
collection is that there can still be memory leaks. If
live, accessible references to unneeded objects are
allowed to persist in a program, then those objects
cannot be garbage collected. Therefore it is better to
explicitly assign null to a variable when it is not
needed any more. This is particularly important when
implementing a collection.
Object lifetime
The lifetime of an object is from the
time it is created to the time it is garbage
collected. The finalization mechanism does provide a
means for resurrecting an object after it is no longer
in use and eligible for garbage collection, but
finalization is rarely used for this purpose.
Cleaning up
Objects that are created and accessed
by local references in a method are eligible for
garbage collection when the method terminates, unless
references to those objects are exported out of the
method. This can occur if a reference is returned or
thrown as an exception.
Object finalization
protected void finalize()
throws Throwable;
A finalizer can be overridden in a
method in a subclass to take appropriate action before
the object is destroyed. A finalizer can catch and
throw exceptions like other methods. However, any
exception thrown but not caught by a finalizer when
invoked by the garbage collector is ignored. The
finalizer is only called once on an object, regardless
of being interrupted by any exception during its
execution. In case of finalization failures the object
still remains eligible for garbage collection at the
discretion of garbage collector unless it has been
resurrected.
Finalizer chaining
Finalizers are not implicitly chained
like constructors for subclasses, therefore a
finalizer in a subclass should explicitly call super
class finalizers as its last action.
A finalize method may make the object
accessible again, thus avoiding it being garbage
collected. One simple technique is to assign its
this reference to a
static variable, from
which it can later be retrieved. Since a finalizer is
called only once on an object, an object can be
resurrected only once.
finalize () method:
Sometimes an object will
need to perform some action when it is destroyed by
the garbage collector. For example, if an object is
holding some non java resources such as a file handle
or window character font, then you might want to make
sure these resources are freed before an object is
destroyed. By using finalization, you can define
specific actions that will occur when an object is
just about to be reclaimed by the garbage collector.
To add a finalizer to a class, you simply define a
finalize() method. This method has the general form:
protected void finalize
();
You might find that the
storage for an object never gets released because your
program never nears the point of running out of
storage. If your program completes and the garbage
collector never gets around to releasing the storage
for any of your objects, that storage will be returned
to the operating system en masse as the program exits.
This is a good thing, because garbage collection has
some overhead, and if you never do it you never incur
that expense.
Finalizers are guaranteed to be called before the
memory used by an object is reclaimed. However there
is no guarantee that any memory will ever be
reclaimed. Hence there is no guarantee that finalize(
) will ever be called. There is a promise that barring
catastrophic error conditions, all finalizers will be
run on leftover objects when the Java virtual machine
exits. However this is likely too late if your program
is waiting for a file handle to be released. Besides
it is not convincing that it happens anyway. Therefore
it is vital that you never rely on a finalizer to free
finite resource, such as file handles, that may be
needed late by your program.
Sections :
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11
|