解释这个 System.gc() 行为
Explain this System.gc() behavior
在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();
}
}
在我看来,诀窍是创建一个新的对象引用而不是分配它:new PrintMessage();
.
这就是让我感到困惑的地方。当我编译并 运行 这个程序时,我得到以下预期输出:
:P
Error. Message is: :P
但是,如果我像这样修改 main() 函数的第一行:
(new PrintMessage(":P")).getMessage();
我没有看到任何输出。为什么只有当我将输出发送到标准输出时 System.gc()
才调用垃圾收集器?这是否意味着 JVM 仅在看到某些 "real" 用途时才创建对象?
对象将被创建,字节码编译器不会优化它。在第二种情况下发生的情况是,您的程序在输出实际刷新到您的终端之前退出(或者甚至可能在终结器 运行 之前退出,您永远不知道 GC 和终结实际发生的时间)。如果在 System.gc()
调用后添加 Thread.sleep()
,您将看到输出。
在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();
}
}
在我看来,诀窍是创建一个新的对象引用而不是分配它:new PrintMessage();
.
这就是让我感到困惑的地方。当我编译并 运行 这个程序时,我得到以下预期输出:
:P
Error. Message is: :P
但是,如果我像这样修改 main() 函数的第一行:
(new PrintMessage(":P")).getMessage();
我没有看到任何输出。为什么只有当我将输出发送到标准输出时 System.gc()
才调用垃圾收集器?这是否意味着 JVM 仅在看到某些 "real" 用途时才创建对象?
对象将被创建,字节码编译器不会优化它。在第二种情况下发生的情况是,您的程序在输出实际刷新到您的终端之前退出(或者甚至可能在终结器 运行 之前退出,您永远不知道 GC 和终结实际发生的时间)。如果在 System.gc()
调用后添加 Thread.sleep()
,您将看到输出。