Finalization method in <Thinking in java, 4th Edition>
I am reading Thinking in Java, 4th edition. I found the problem: when I tested the source code in the Eclipse IDE, I found that the results are different. Hope someone can help me!
Here is the source code
class Book { boolean checkedOut = false; Book(boolean checkOut) { checkedOut = checkOut; } void checkIn() { checkedOut = false; } protected void finalize() { if(checkedOut) System.out.println("Error:checked out"); //Normally,you'll also do this: //super.finalize();//Call the base-class version } } public class TerminationCondition { public static void main(String[]args) { Book novel=new Book(true); //Proper cleanup: novel.checkIn(); //Drop the reference,forget to clean up: new Book(true); new Book(true); new Book(true); //Force garbage collection & finalization: System.gc(); } }
Book result:
Error: Checked out
IDE Result
(nothing)
Java version I am using:
Java version "1.7.0_51"
Java (TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot (TM) 64-bit Server VM (build 24.51-b03, mixed mode)
The Java version in the book is Java 5. Did something change the finalize method?
source share
The JVM has its own garbage collection policy, even if you call it finalize()
separately or not! The JVM does so optimally that the user does not need to interfere with the garbage collection process.
So, what you are seeing has nothing to do with the Java version or anything! It totally depends on the JVM and its automatic memory management policy.
source share
The Java version in the book is Java 5. Did something change the finalize method?
If you read the specs for System.gc()
and related things, you will see that there is no guarantee of what will happen:
-
It is not guaranteed that the call
System.gc()
will lead to anything at all. Seriously. -
Collection of all garbage is not guaranteed.
-
Garbage objects are not guaranteed to complete ... failing method
finalize()
.
The real problem is that the example you are looking at is making unfounded assumptions. This happened in older versions of Java. It doesn't work with later ones ... or something like that. This is just a bad example.
But this (I hope) shows you that it is unwise to rely on methods finalize
that are called at a predictable time. In fact, it's best not to use finalize
for anything ... other than "belt and curly braces", clean up the code.
In fact, finalization usually occurs after the garbage collection has completed. (This is done by the daemon's finalization thread, which runs through all objects that have been identified as inaccessible and require termination.) So what is probably happening in your example is that the JVM exits after starting the GG, but before finalizing, the thread is able to handle the terminated objects.
source share