Explain this behavior of System.gc ()

In Thinking in Java, the author suggests a method for enforcing garbage collection on an object. I wrote a similar program to test this (I'm on Open JDK 7):

//forcing the garbage collector to call the finalize method
class PrintMessage
{
    private String message;

    public PrintMessage (String m)
    {
        this.message = m;
    }

    public String getMessage()
    {
        return this.message;
    }

    protected void finalize()
    {
        if(this.message == ":P")
        {
            System.out.println("Error. Message is: " + this.message);
        }
    }
}

public class ForcingFinalize
{
    public static void main(String[] args)
    {
        System.out.println((new PrintMessage(":P")).getMessage());
        System.gc();
    }
}

      

The trick, I think, is to create a new link to the object and not the designation: new PrintMessage();

.

That's what puzzles me. When I compile and run this program, I get the following expected output:

:P
Error. Message is: :P

      

However, if I modify the first line of my main () function like this:

(new PrintMessage(":P")).getMessage();

      

I see no way out. Why System.gc()

does it only call the garbage collector when sending output to standard output? Does this mean that the JVM only creates an object when it sees some "real" use for it?

+3


source to share


1 answer


The object will be created, the bytecode compiler will not optimize this. What happens in the second case is that your program exits before the output actually turns red to your terminal (or maybe even before the finalizer runs, you never know when GC and finalization actually occurs) ... If you add Thread.sleep()

after the call System.gc()

, you will see the output.



+4


source







All Articles