The finalize in Object.java is an empty function, Where is the heavy work of cleaning the object happening ?
Inside the JVM, as part of the garbage collector. You don't have access to any of this logic.
Finalizer is called when object is garbage collected. Which means it should not call 'bar' How is bar still being printed.
Not exactly. finalize()
is called at any point between the moment the object has no references (and thus is ready for collection) and the moment the VM decides to effectively reclaim it, but before effectively doing it. This is important because finalize()
could not only print "bar", but even establish references (by executing AClass.aStaticField= this ;
, as a very simple example) that make the object or other objects previously eligible for collection again "alive". For this reason, the object's eligibility for garbage collection is checked again after finalize()
and collection possibly aborted. By doing this, objects can refuse to be garbage collected, but not forever (see below).
Additional ideas that could help understanding finalize()?
- It's not equivalent to a destructor at all.
- It exists mainly for historical reasons. The original idea was to give objects a chance of cleaning up resources (TCP connections, open files, etc.) before being collected. However, the period that can pass between object "release" and
finalize()
is so variable that explicit resource de-allocation through close()
methods became the preferred ("Javatic"?) way and finalize()
use has been discouraged. In fact, many JVMs do not call any finalize()
method when terminating.
- One good example of the preference I mention above is the "try with resources" construct introduced in Java 7. In contrast, nothing has been done to correct the challenges presented by
finalize()
. Ever.
- The ability of
finalize()
to "resurrect" not only its own object, but also other objects has consequences not fully specified. What has been specified is: "The finalize method is never invoked more than once by a Java virtual machine for any given object.". This means that if finalize()
"resurrects" its own object, it will not be called a second time even the object is ready for collection again. Very curious behavior to say the least. Random in fact if two objects interplayed this way, as Java doesn't guarantee any order while collecting objects.
- In summary: do not use
finalize()
. If you did, you would be one of the first persons depending on it for anything. The idea was good, in principle, but there was no way of anticipating the consequences that became apparent in time. Do define explicit close()
methods for resource cleanup. In some cases, cleanup threads that monitor resource usage can also be useful.
PS: Something very similar happened with Thread.suspend()
, Thread.resume()
, Thread.stop()
, and Thread.destroy()
. Very nice ideas that practice proved a nightmate in terms of application and JVM stability. The only difference is that these Thread
methods have been officially deprecated because their impact is (debatably) bigger.