The main indications that conditions are common for a leak are mismatched
add / remove pairs, mismatched life cycles, and other kinds of anchors with
longer life cycles. Singletons and static classes can often provide safe harbor
for memory leaks.
Solution 2: Aggressively pair adds with removes
To effectively deal with collection-based memory leaks, you might have to
change your programming hygiene. Consider collection management with all
CRUD operators: Create, Read, Update, and Delete. Any time you add a row
to a collection, you need to add the corresponding remove. In fact, you
should do both at the same time so you don't forget. Further, if possible,
ensure that the pairs are in close proximity in the code. In addition, you can
tag the pairs with a comment or with the name of the collection so that you
can easily use strategies to look for pairings when you have to refactor or deal
with a memory leak. Then, you can use tools such as GREP to scan the program
and look for pairs. In some cases, proximity may not be an option, like the use
of a cache. For these collections, you can use a different utility to periodically
prune the cache to remove elements that have timed out. In these cases, dif-
ferent strategies will be required.
Solution 3: Use soft references for caches
Though inconsistent implementation diminishes their value, caches (and ses-
sion state managers, a special case of the cache) are collections that demand a
different approach. We'd like the cache to use all available memory, and be
freed only when the system needs the additional resources. Fortunately, Java
soft references provide a mechanism that can do exactly that. An object is said
to be softly reachable if it can be reached only through use of a soft reference.
The Java 1.3 specification says that softly reachable objects can be freed at the
garbage collector's discretion with two caveats:
The garbage collector will attempt to free soft references before throw-
ing an out-of-memory exception.
The garbage collector should attempt to free soft references in least
recently used order.
These properties make soft references ideal for the implementation of caches.
In practice, some garbage collectors treat soft references like weak references,
diminishing their value in caches. Clearly the intent of the soft reference is for
use in such applications as memory-sensitive caches. While the JVM s should
attempt to free soft references in the least recently used order, many do not.