As worded the sentence is not really true since all objects are not necessarly garbage collected before the program ends for various reasons (abrupt completion of main, System.exit()...) For the question to be correctly worded I'd add something to it: "The finalize() method will eventually be called on every object that has become eligible for garbage collection". Here is what the API says about this:
The general contract of finalize is that it is invoked if and when the JavaTM virtual machine has determined that there is no longer any means by which this object can be accessed by any thread that has not yet died
Originally posted by Valentin Crettaz: "The finalize() method will eventually be called on every object that has become eligible for garbage collection".
These questions have always given me trouble. What do we really know about how garbage collection is performed? Obviously, not all object will eventually have their finalize methods called, becuase not all objects will be garbage collected. But, when an object becomes eligible for garbage collection, does the finalize method get called immediately on that object? From your statement above, it would seem that this is the case. However, I didn't think that was true. I thought the finalize method would be called whenever the JVM decided to run garbage collection or when you explicitly call System.runFinalization(). One thing I've always wondered about is, are finalize methods called by the same thread that is responsible for performing garbage collection, or are there two separate threads that perform these functions?
Any clarification would be greatly appreciated. Thanks, Corey
The finalize method is never invoked more than once by a Java virtual machine for any given object. Any exception thrown by the finalize method causes the finalization of this object to be halted, but is otherwise ignored. (my note: garbage collection for this object is not halted, only the execution of it finalize is) The Java programming language does not guarantee which thread will invoke the finalize method for any given object. The general contract of finalize is that it is invoked if and when the JavaTM virtual machine has determined that there is no longer any means by which this object can be accessed by any thread that has not yet died, except as a result of an action taken by the finalization of some other object or class which is ready to be finalized. (my note: first step, all the finalizers methods haven't runned yet) After the finalize method has been invoked for an object, no further action is taken until the Java virtual machine has again determined that there is no longer any means by which this object can be accessed by any thread that has not yet died, including possible actions by other objects or classes which are ready to be finalized, at which point the object may be discarded. (my note: second step, all the finalizers methods have already runned)
I think the API give us the clue that there are two steps before the collection of an object's memory: a) first step The object must be determined unreachable. Though, because it could be made reachable (resurrected) again by any finalize method, it can not be recollected yet. b) second step The JVM again determine that the object is unreachable, even from all the finalize methods of the unreachable objects. That is, all the finalize methods that were able to resurrect this object have already runned. Thus the object can not be resurrected, and its memory can be reclaimed.
SCJP2. Please Indent your code using UBB Code
Joined: Jul 03, 2001
This code shows how the collection of objects with a finalize method takes two steps of the collector.
A phantom reference is enqued by the collector when the finalize methods are runned. In this way it ensures that the object is not resurrectable. The first call to the collector executes the finalize method. The second enques the reference, now the action of finalization can be made without fear of the object being resurrected. When these actions are done, the programmer calls clear to make the object unreferenced and to allow the recycling of its memory. But if you uncomment the lines things get more interested. I have seen that the second call to the collector is not able to enque the reference because not all the finalize methods were runned by that time. In my computer the third call to the collector occurred after the execution of all the finalize methods, and thus the last created phantom object was enqued.
First, the JLS doesn't guarantee that garbage collection (gc) will ever occur, nor does it state the implemention/algorithm of how and when gc is to take place. Therefore it is false to assume that the finalize() method will ever get called, actually it is discouraged to use this as a way of doing last minute clean up in real-word programs, and I think that Sun should have deprecated this part of Java a long time ago Also the JLS states that "should" an object be GCed, the finalize() methods will be called once and only once. What is the ramification of this? Well, it's possible to save a reference of the object being GCed within the finalize method thereby preventing that object from being CGed. The next time this object become eligible for GC the finalize method will not get called.
<a href="http://www.rajindery.com" target="_blank" rel="nofollow">Rajinder Yadav</a><p>Each problem that I solved became a rule which served afterwards to solve other problems. --Rene Descartes