Re: finalize() overhead
Joe Seigh wrote:
Eric Sosman wrote:
Joe Seigh wrote:
I guess overriding finalize() isn't recommended too much because
of it's adverse effect on GC performance. But I assume that
if it's used a lot. You need finalize() for things like guaranteeing
proper clean up of non-memory resources like file descriptors and
db connections. One way anyway.
So this sort of use of finalize is considered acceptable? Or should
it be avoided at all costs even if you leak file descriptors or
whatnot?
Can't remember who said it (Bloch? Eckel? not sure), but
the thing to keep in mind is that finalize() is a creature of
the garbage collector, the garbage collector's concern is
memory and memory only, so finalize() should be about memory
and memory only. Eckel (I'm sure, this time) also suggests
a debugging role: If an object becomes garbage without its
close() or dispose() or disconnect() method being called, a
finalize() can emit a warning message to that effect.
If you need to get rid of file handles, database connections,
windows, sessions, sockets, locks on the frammis interface, or
other non-memory kinds of things, you should provide a close()
or dispose() or terminate() or ahhScrewItAll() method to shut
down, release, relinquish, or otherwise sever your association
with such entities. The finalize() method is *not* the right
vehicle for such things; finalize() is *not* a "destructor."
The key word here is guarantee. Obviously the proper way is to
use a close method but the mere existence of such a method doesn't
guarantee its proper use.
Enforcing proper use seems beyond the capabilities of an
API. Hence Eckel's suggestion to use finalize() as a debugging
aid: for an object that *should* be dispose()d, you imlement
a finalize() that tests the object's status and whines if the
object became garbage with no dispose(). It's not perfect --
you can't be sure all objects will be finalized -- but it may
help you catch a few bugs.
It sounds like most of the objection here is aesthetic. Any
technical issues (beside the GC not offering any real time
guarantees)?
Not only does GC offer no real time guarantees, it offers
no guarantees at all. The JVM can exit -- usually *does* exit --
with garbage uncollected, hence with garbage un-finalized. If
you use finalize() for something important, there is every chance
that the important something will never be done at all. (No, not
even with runFinalizersOnExit(), although I'm not deeply enough
versed in the matter to explain all the whys and wherefores: in
this I'm just trusting the word of others.)
Summary: If it needs doing, don't rely on finalize() to do it.
Use finalize() only when you're perfectly happy if "it" remains
un-done when the JVM exits.
--
Eric Sosman
esosman@ieee-dot-org.invalid