Java Reference
In-Depth Information
PropertyChangeListener listener)
{
listeners_.removePropertyChangeListener(listener);
}
}
In this case, class C is registering a
propertyChanged
method with a static lis-
tener. Since D is a singleton (and has a long life cycle), it will remain reach-
able. Though the reference to C is removed in
main
, we have a memory leak.
We can solve this solution in one of three ways.
6.3.2
Solution 1: Explicitly remove the listeners
You can solve this problem by explicitly removing listeners whenever you add
them. With the graphical components, the places for removing listeners are
well defined. The
Frame
and
Dialog
classes in the Java
AWT
library fire the
dispose()
method when the associated window is destroyed. Classes that add
listeners and inherit from
Frame
or
Dialog
will also want to override the
dis-
pose()
method and add a call to remove the event listener. For subclasses of
components, cleanup can occur when the component is removed from the
parent's container. This action fires the
removeNotify
method, which can be
subclassed for the addition of the proper cleanup code. For property change
listeners, the call is
removePropertyChangeListener
; for event listeners, the
call is
removeActionListener
.
For other classes like the one in listing 6.3, there's no logical place. Since
finalize
is triggered by garbage collection and we're trying to remove refer-
ences that will inhibit garbage collection, we have to invent a method and call
it when we've finished using the class. It's better to place this code in close
proximity to the code that registers the event listener. Both the
add
and the
associated
remove
methods should be commented.
Finally, it's important to periodically verify that
addSomeKindOfListener
calls are paired with the associated
removeSomeKindOfListener
calls. If both
lines are in close proximity, verification is simple. If not, the calls can be paired
with a text search, like
grep
.
6.3.3
Solution 2: Shorten the life cycle of the anchor
One way to ensure that a listener will be garbage collected is to make sure that
the listener registry can be garbage collected. Listing 6.2 does not have a
memory leak because the registry is a short-lived component. This is usually
not the best solution by itself, because it leaves
addActionListener
calls