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?

+3


source share


3 answers


Your main thread exits before GC starts. So you don't get any information. Make the following changes in the main method and you will see the result: -



System.gc();
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

      

0


source


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.

+1


source


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.

0


source







All Articles