当前位置: 首页 > 面试题库 >

方法中未使用的局部变量是否会在JVM中获取内存?

葛泳
2023-03-14
问题内容

我在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文档章节没有提到从堆栈中删除未使用的变量。因此,除非有进一步的发现,我的答案是它与实现有关,但似乎是任何自重的编译器都会执行的优化。还要注意,这是一个局部变量而不是字段也没关系-
实际上,局部变量是最有可能被优化的变量,因为它们最容易分析和消除。(正是因为它们是本地的)



 类似资料:
  • 问题内容: 嗨,我正在浏览有关内部类的SCJP书,发现了这一说法,类似这样。 方法本地类只能引用已标记的本地变量 在解释中,指定的原因与本地类对象和堆上的局部变量的范围和生存期有关,但我无法理解。我在这里想念任何东西吗? 问题答案: 原因是,在创建方法本地类实例时,编译器实际上会将其引用的所有方法本地变量复制到其中。这就是为什么只能访问变量的原因。甲变量或参考是不变的,所以它停留在同步与其方法本地

  • 本文向大家介绍是否可以在C / C ++中访问局部变量的内存?,包括了是否可以在C / C ++中访问局部变量的内存?的使用技巧和注意事项,需要的朋友参考一下 让我们看一个示例,您可能可以访问超出其范围的局部变量的内存。 示例 输出结果 这可能会给出输出- 如前 ,此代码可以正常工作。我们只是在读取和写入内存,将USED用作x的地址。总的来说,您超出了foo的范围,该地址是指向某个随机内存区域的指

  • 我正在分析的类: 我正在尝试使用MethodDeclaration获取变量名,但无法做到这一点。 我正在尝试获取此is的输出。 verifyAgeLimit():此。名称或名称 verifyAgeLimit():此。名称或名称 showAddress():此。地址或地址 我试图将整个方法转换为sting并读取字符串以找出名称,但它变得太复杂,而且精度也很低。 有什么办法可以解决吗?

  • 问题内容: 我正在寻找类似于ThreadLocal的类,该类将在线程组而不是线程上工作。 如果没有这样的类(在某些开源库中),您将如何实现它?比在WeakHashMap中拥有线程组更好的主意? 我正在使用全局,每个线程和每个线程组上下文中的各种参数在运行时实现可调试的调试框架。作为一个非常简单的示例,您可以有一个报告语句: 并指定只有当服务网络请求的线程组中的某个线程调用该线程时,才会显示具有该特

  • 我有一个类需要测试。以下是的定义: 并根据值从数据库中检索一些要操作的数据。对于该数据库,值通过JSON文件持久化。 这使事情复杂化了。我需要的是在测试时将其设置为某个特定的日期。有没有办法可以用mockito模拟局部变量的值?

  • 问题内容: 我想知道使用最终局部变量是否有可用性。当继承出现时,变量无论如何都不会被覆盖。例如下面的简单代码 这个例子很简单,可能不是一个相关的代码,但是问题比较笼统。我已经看到了很多代码(全部都包含在具有最终局部变量的main函数中)是否有将局部变量声明为final other的可用性。不能在同一功能中进行编辑? 问题答案: 首先,关于变量被“覆盖”的部分具有两个非常不同的含义。对于类和方法,它