在没有返回值的接收者对象的情况下调用非空方法时,JVM会做什么? 它只是在找不到收件人的那一刻破坏了返回的对象?还是让返回的对象由垃圾收集器管理?或者是其他东西?。例如:
public class PrincipalClass {
public static void main(String[] args) {
returnStringMethod();
}
public static String returnStringMethod() {
return "Hello, Java world!";
}
}
“您好,Java世界!”发生了什么?那退还了吗在什么时间被摧毁?
答案 0 :(得分:1)
想象一下您点了饭。这顿饭装在一次性的盒子里。你拿出食物吃了。现在这些盒子对您来说毫无用处。您如何处理它们?丢弃它们。 Java GC也是如此。当没有通过任何对象引用或无法访问任何对象时,它将在下次触发gc时获得。看到这种情况的一种好方法是打开jvisualvm并继续跟踪String文字,然后启动gc。您会实时看到事情。
我希望这会有所帮助..!
答案 1 :(得分:1)
在这种情况下,返回值/引用将被简单地丢弃。可以将其视为立即超出范围的局部变量。
此外,由于没有实时引用,因此可以使用GC。因此,在将来的某个时候(不是马上),该对象将被GC化。
答案 2 :(得分:1)
编译程序时,例如使用javac
并运行命令javap -c PrincipalClass
(javap
是JDK附带的命令),您将看到以下输出:
Compiled from "PrincipalClass.java"
public class PrincipalClass {
public PrincipalClass();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: invokestatic #2 // Method returnStringMethod:()Ljava/lang/String;
3: pop
4: return
public static java.lang.String returnStringMethod();
Code:
0: ldc #3 // String Hello, Java world!
2: areturn
}
关键部分是方法main
,由字节码指令invokestatic
,pop
,return
组成。
invokestatic
指令将调用方法returnStringMethod
,并在操作数堆栈上保留对String
的引用。随后的pop
指令将删除最上面的堆栈条目,即引用。该指令之后,当前方法不再引用该字符串。因此,如果它不是可从代码中引用的字符串文字,则可以进行垃圾回收。具体来说,它与ldc
中的returnStringMethod()
指令相关联。
原则上,这里不需要pop
指令,因为return
指令会破坏当前方法的整个堆栈帧,包括其操作数堆栈。
在任何一种情况下,答案都是垃圾回收器的使用,垃圾回收器可能在以后发现没有对该对象的引用。至少这是正式运作的方式。 JVM中还有一个优化器,可以检测方法是否忽略直接在被调用方法中创建的对象,并优化此特定代码。但是,结果更像是一开始就从不创建对象,而不是之后立即销毁它。而且,此优化器仅查看与性能相关的代码。
另一点是,对于您的简单程序,垃圾收集器可能永远不会运行,因为在较短的执行时间内不需要垃圾收集器。 JVM终止时,将立即释放整个堆内存。