Java 解释这个System.gc()行为

Java 解释这个System.gc()行为,java,garbage-collection,Java,Garbage Collection,在《用Java思考》一书中,作者提供了一种强制对象垃圾收集的技术。我编写了一个类似的程序来测试这一点(我在OpenJDK7上): 在我看来,诀窍在于创建一个新的对象引用,而不是分配它:newprintmessage() 让我困惑的是。当我编译并运行此程序时,我得到以下预期输出: :P Error. Message is: :P 但是,如果我像这样修改main()函数的第一行: (new PrintMessage(":P")).getMessage(); 我没有看到任何输出。为什么只有当我将输

在《用Java思考》一书中,作者提供了一种强制对象垃圾收集的技术。我编写了一个类似的程序来测试这一点(我在OpenJDK7上):

在我看来,诀窍在于创建一个新的对象引用,而不是分配它:
newprintmessage()

让我困惑的是。当我编译并运行此程序时,我得到以下预期输出:

:P
Error. Message is: :P
但是,如果我像这样修改main()函数的第一行:

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

我没有看到任何输出。为什么只有当我将输出发送到标准输出时,
System.gc()
才调用垃圾收集器?这是否意味着JVM仅在看到对象的某些“实际”用途时才创建该对象?

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

如果在循环中调用此函数,编译器可能最终会对其进行优化。实际上,它可能会被JIT:ed处理掉。我指的是字节码编译器will clearify。@Kristofere好的,它在添加
Thread.sleep()
:-)后工作
(new PrintMessage(":P")).getMessage();