Java Reference
In-Depth Information
within a certain amount of time; how long to wait should be determined empirically, and fail-
ures must then be analyzed to ensure that the problem wasn't just that you didn't wait long
enough. (This problem is not unique to testing concurrent classes; sequential tests must also
distinguish between long-running and infinite loops.)
12.1.4. Testing Resource Management
The tests so far have been concerned with a class's adherence to its specification—that it does
what it is supposed to do. A secondary aspect to test is that it does not do things it is not sup-
posed to do, such as leak resources. Any object that holds or manages other objects should
not continue to maintain references to those objects longer than necessary. Such storage leaks
prevent garbage collectors from reclaiming memory (or threads, file handles, sockets, data-
base connections, or other limited resources) and can lead to resource exhaustion and applic-
ation failure.
Resource management issues are especially important for classes like Boun-
dedBuffer —the entire reason for bounding a buffer is to prevent application failure due to
resource exhaustion when producers get too far ahead of consumers. Bounding causes overly
productive producers to block rather than continue to create work that will consume more
and more memory or other resources.
Undesirable memory retention can be easily tested with heap-inspection tools that measure
application memory usage; a variety of commercial and open-source heap-profiling tools can
do this. The testLeak method in Listing 12.7 contains placeholders for a heap-inspection
tool to snapshot the heap, which forces a garbage collection [5] and then records information
about the heap size and memory usage.
The testLeak method inserts several large objects into a bounded buffer and then removes
them; memory usage at heap snapshot #2 should be approximately the same as at heap snap-
shot #1. On the other hand, if doExtract forgot to null out the reference to the returned
element ( items[i]=null ), the reported memory usage at the two snapshots would defin-
itely not be the same. (This is one of the few times where explicit nulling is necessary; most
of the time, it is either not helpful or actually harmful [EJ Item 5].)
12.1.5. Using Callbacks
Callbacks to client-provided code can be helpful in constructing test cases; callbacks are often
made at known points in an object's lifecycle that are good opportunities to assert invari-
Search WWH ::




Custom Search