方法中未使用的局部变量是否会在JVM中获取内存?
问题内容:
我在SO中碰到过这篇文章。未初始化的原始实例变量是否使用内存?
它指出:“在Java中,声明类级实例变量而不初始化它会消耗内存吗?例如:int i;如果我不使用i = 5初始化它,是否使用任何内存;”
我的问题是在局部变量的情况下,说我有一个方法foo()
public int foo(){
int x;
//Write code which does not use/initialize x
}
局部变量会x
占用内存吗?
编辑
乔恩的答案是
更新:对此进行了更多研究,我发现此页面向我暗示,尽管编译后的字节码暗示为x分配了空间,但jvm确实可以对其进行优化。不幸的是,我找不到所执行优化的完整描述。特别是,关于编译的JVM文档章节没有提到从堆栈中删除未使用的变量。因此,除非有进一步的发现,我的答案是它与实现有关,但似乎是任何自重的编译器都会执行的优化。还要注意,这是一个局部变量而不是字段也没关系-
实际上,局部变量是最有可能被优化的变量,因为它们最容易分析和消除。(正是因为它们是本地的)
让我们看看是否可以找到更多证据支持这一点。
问题答案:
这是一个值得用javap研究的问题。
public class Foo
{
public int bar(){
System.out.println("foo");
return 8;
}
public int foo(){
int x;
System.out.println("foo");
return 8;
}
}
请注意,foo()和bar()之间的区别在于,一个声明局部变量x,而另一个则不声明。
现在看一下jvm代码(用来javap -v Foo
在您的机器上查看)
public int bar();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String foo
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: bipush 8
10: ireturn
LineNumberTable:
line 6: 0
line 7: 8
public int foo();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String foo
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: bipush 8
10: ireturn
LineNumberTable:
line 12: 0
line 13: 8
}
有趣的是,逐行输出是相同的,但是bar的局部变量是1,而foo的局部变量是2。因此,即使编译器输出从未使用过,x的空间似乎确实已分配。它。
更新:对此进行了更多研究,我发现此页面向我暗示,尽管编译后的字节码暗示为x分配了空间,但jvm确实可以对其进行优化。不幸的是,我找不到所执行优化的完整描述。特别是有关编译的JVM文档章节没有提到从堆栈中删除未使用的变量。因此,除非有进一步的发现,我的答案是它与实现有关,但似乎是任何自重的编译器都会执行的优化。还要注意,这是一个局部变量而不是字段也没关系-
实际上,局部变量是最有可能被优化的变量,因为它们最容易分析和消除。(正是因为它们是本地的)