Related link: http://www-106.ibm.com/developerworks/library/j-jtp01274.html
Brian Goetz
>reckons that garbage collection in modern Java Virtual Machines is now so good that we Java programmers do best by leaving it alone. I don’t buy it.*
>Defensive programming is a strategy where you may put in
“extra” code to just in case the world is not perfect.
For example, the defensive programmer puts in assert()s
to check invariants that are inconceivable to fail
and explicit tests for invariants that could conceivably
go wobbly.
Mr. Goetz is down on explicit nulling, as generally pointless.
But after minor collections the new generation
includes objects that aren’t necessarily alive but can’t be reclaimed, either because they are directly alive, or because they are within or referenced from the old generation according to
>Sun.
So when dealing with a large, long-lived, dynamic data structure that is passed around various methods (think of a big DOM or, if it helps, an unwanted haggis brought by a Scottish aunt), you might find that some of its objects are old generation and some are in the new. In that case,
the defensive programmer may
decide to have a cleanup method at the root object of the data structure to traverse the data structure to some depth, to reduce the chances that new generation objects have
references from the old. To give the minor collector
a hand.
The defensive programmer might also decide to explicitly null the references as soon as possible so that the object is not alive if there is a full GC before the end of the method or the object with the reference.
Whether you think the example is a kind of exceptional case
obviously depends on what kind of application you think is
normal. Java has been well designed for servers
and small applications, which fits in well with Sun and IBM’s
web-client/server architecture. Indeed, much advice
on the Web tacetly assumes servers or applets; fair
enough. But those of us making
desktop applications using Java sometimes have
special needs.
We like minor collections and want them to be as effective as possible, and we want to
system.gc() to encourage major collections to
occur at times that the user is at rest:
for example, when opening the first file and
whenever a large file is closed.
(Contrast this with Mr. Goetz’s suggestion of using -XX:+DisableExplicitGC, though he has
a typically good point that libraries should avoid
unconditional system.gc(): leave it
to your GUI code.)
Now, you should at this stage be thinking “Mmmmaybe, but
surely profiling is the better way to go: only fix problems that you can see actually exist, not phantom ones!”
This is where defensive programming comes in:
the defensive programmer thinks “Well, the trouble
with profiling is the trouble with most empirical
>benchmarking
approaches: they may be focussing on behaviour that is
unexpected or wrong rather than behaviour that is suboptimal” because the performance of large, multi-threaded
desktop applications can be quite hard to capture.
(If your problems occur because you are fondling the
nether limits of your memory, your profiler might
be straining also.)
Actually, in many cases you may not be using
a profiler at all, for whatever reason. If you are not
using a profiler, then defensive programming may
reduce the effect of some problems (such as unreleased
listeners) that profiling makes obvious. If you are
using a profiler, defensive programming may be worth
it just to smooth out lumps in performance and
reduce the application developer’s nightmare: when
the user suddenly has a data set and use-pattern that
brings out the worst in your application.
So I suspect that
sometimes explicit nulling of references is defensible,
sometimes cleanups may help the minor collector,
and sometimes the dreaded System.gc()
is appropriate. So what about the other main point in
the article, against object pooling?
This comes from what looks like an
>excellent presentation
at Java One by the wonderfully named
Dr. Cliff Click. Dr. Click’s page 30 says
pooling “loses for small objects”,
“a wash for medium objects (Hashtables)” and
a “win for large objects”.
But in Mr. Goetz’s article this becomes
“object pooling is a performance loss for all but the most heavyweight objects”, which I think is a
little too enthusiastic, certainly for
single-CPU desktop systems.
Brian Goetz has an excellent collection of
other articles at
>http://www.quiotix.com/~brian/pubs.html
that is well worth a look.
In the more tolerant ’70s, one of my dear
old Dad’s business partners used to sport a
badge “How dare you presume I’m a heterosexual!”
May this is a good slogan for Java desktop application
developers to adapt towards people writing technical
material: “How dare you presume
I’m writing a servlet!”
* Well, at least not for the kinds of desktop
applications I work on.
What are your favourite techniques for defensive programming?



