When an object becomes unreachable, it is flagged as collected by
the garbage collector. If it has a finalize() method, it is marked
for finalization and put in a finalization queue. After
finalization, it becomes finalized. If it does not have a finalize() method,
it is directly marked as finalized without being inserted in
the finalization queue.
The finalization queue is subject to memory limitations like the application itself. One cannot precisely guess when or how often the content of the finalization queue will be processed, though the lower the remaining amount of memory, the higher the probability this process will happen 'soon'.
Once an object has been finalized, it is ready for deallocation. Java guarantees thatfinalize() is never called more than once on an object. If there is no more hard reference to this object after finalization, then the memory used for this object is released. In other words, finalization does not guarantee memory recollection.
The finalization queue is subject to memory limitations like the application itself. One cannot precisely guess when or how often the content of the finalization queue will be processed, though the lower the remaining amount of memory, the higher the probability this process will happen 'soon'.
Once an object has been finalized, it is ready for deallocation. Java guarantees thatfinalize() is never called more than once on an object. If there is no more hard reference to this object after finalization, then the memory used for this object is released. In other words, finalization does not guarantee memory recollection.
Do's
- Do
call the super implementation of finalize() - If you implement afinalize() method
in an object, make sure this method calls finalize()on the super
object (i.e. super.finalize()).
- Double-check that resources have been released - Let's assume an object is referencing a file or any other non memory resource. It is considered a safe practice to double-check that such resource and been closed and released properly in a finalize() method.
Don't
- Don't
do the job of the garbage collector - Let's assume an object has
a list (for example). Do not implement a finalize() method to
clear the list of its elements in order to free memory. It is an
unnecessary overhead. The garbage collector will do this for you very
efficiently and automatically.
- Do
not wait for finalize() to release resources - Assuming resource
object A has a reference to resource B, and object B has a reference to A.
Assuming both A and B wait until the call of finalize() to
release their reference to each other. This may never happen, especially
if there is a static final reference to A or B elsewhere in the
application. Resources should be released explicitly as soon as they are
not required by the application anymore. Don't wait for a call tofinalize().
- The
call order of finalize() methods is unpredictable - Don't make
any assumptions about the call order of finalize() methods.
- Don't
create a hard reference to a finalized object - The finalize()method
is called when an object has become unreachable. Do not create a hard
reference, for example by adding it to a list in another object, because
this will prevent its memory recollection.
If you are implementing a mechanism monitoring the memory
usage of your application, you may call System.runFinalization() to
facilitate the deallocation process and memory recollection (if necessary).