Joe said:
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.
But since finalize() is only guaranteed to run before trying to reuse
memory (not when object is made available for GC) you can't be certain
that it will run. It will also only run once, even if the object becomes
reachable after finalize() is invoked by the GC system.
Anecdote:
I have seen problems with this in one of my projects. Our installation
team complained that the server ran out of file handles, even if they
increased the ulimit. We asked what they did to trigger this and they
said "nothing, we just install the application, run our tests and then
suddenly we have exceptions and the application has aquired X file
handles. Sometimes it releases them again after a while, but then
exception comes back after a few more hours." X in this case was close
to the setting by ulimit. Initially we were unable to reproduce this but
we did find a class releasing a stream without closing it. The fix
remove problem.
So, why did they get the error while we never saw it during
development/testing? The class leaking the file handle was a monitoring
class that got to run every few seconds and hardly created any garbage
at all. So we used up file handles faster than memory IFF nothing else
ran. Of course that never happened for us, we would either run unit
tests or duration tests, but no test just started the application and
left it alone for >12 hours (the time it took us to trigger the error
once we knew the problem). Since the installation team often let this
application alone after installation they triggered the error. The
application was robust (apart from causing exceptions ;-) ) that after a
while it would run scheduled tasks that caused enough garbage to invoke
a GC which in turn caused the file handles to be released.
Now we actually include statistics of file handles during load and idle
and verify that we get expected results (which sometimes causes us to
change code or change our expectations).
//Roger Lindsjö