解释这个System.gc()行为

时间:2015-04-23 14:25:57

标签: java garbage-collection

Thinking in Java 一书中,作者提供了一种强制对象的垃圾收集的技术。我写了一个类似的程序来测试它(我在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();
    }
}

在我看来,技巧是创建一个新的对象引用而不是分配它:{​​{1}}。

这就是让我神秘的事情。当我编译并运行该程序时,我得到以下预期输出:

new PrintMessage();

但是,如果我修改main()函数的第一行,如下所示:

:P
Error. Message is: :P

我没有看到任何输出。为什么(new PrintMessage(":P")).getMessage(); 仅在我将输出发送到标准输出时才调用垃圾收集器?这是否意味着JVM只有在看到某些“真实”用途时才创建对象?

1 个答案:

答案 0 :(得分:4)

将创建对象,字节码编译器不会对其进行优化。在第二种情况下发生的情况是,在输出实际刷新到终端之前程序退出(或者甚至在终结器运行之前,您永远不知道GC和终结何时实际发生)。如果您在Thread.sleep()来电后添​​加System.gc(),则会看到输出。