This question already has an answer here:
- Java and manually executing finalize 3 answers
- When is the finalize() method called in Java? 16 answers
As far as my understanding goes finalize() and GC are two different aspects. GC uses finalize() method to free Object memory. We cannot state when GC will occur(even if we explicitly call System.gc()). But we can explicitly call finalize() on an Object.
Will the function be executed immediately(memory freed) or it waits till GC
occurs like System.gc() call?
Also as per the docs the finalize method is never invoked more than once by a Java virtual machine for any given object.
So what happens when we call finalize() first and GC happens at a later point of time.
If object memory is not freed on explicit call to object.finalize() then would't
it being called again in the GC process violate the calling only once rule?
As per docs:
However, you cannot force GC to run, you can just kindly ask it via
System.gc()
. So best approach is putting resource-freeing code intofinalize()
method when overriding.You have got it completely wrong.
Short answer:
finalize()
is a means to clean up resources (such as open files) just before the object is ready for garbage collection ( when no object has strong reference to it). It might/not be called. It is one step ahead of memory deallocation.Long answer:
There is a separate daemon thread called as finalizer thread which is responsible for calling finalize() method . Finalization queue is the queue where objects which are ready to be called finalize() method are placed.
When an object is ready for garbage collection, then the garbage collector thread checks if this particular object has finalize() from table mentioned in (1).
2a) If it doesn’t then it is sent for garbage collection.
2b) It is has, then it is added to the finalization queue. And it removes the entry of the object from the table (1).
Finalizer thread keeps polling the queue. For every object in the queue, its finalize() method is called. After calling the finalize() cycle from (2) is again repeated. If this object still has no strong reference, then sent for GC. If it has then ALWAYS (2a) is called because the entry was deleted in (2b)
So what’s the issue with the above cycle?
You do not know when finalize() is called as you have no control over when GC is called. Sometimes it might happen that you are printing the value’s in finalize() but the output is never shown, because your program might have got terminated by the time finalize() is called.
Hence avoid using it. Instead create a method say dispose() which will close the necessory resources or for final log etc.
Answers are in Object.finalize API
1) GC calls finalize() so finalize() and GC are NOT two different aspects
2) You should not call finalize manually, but if you do it will not will not free any memory and it will not affect GC behaviour
3) It is said that it's guaranteed that GC will not call finalize twice, our calls do not count