【问题标题】:Heap and Stack when I use an instance variable in a method (Java Memory)当我在方法中使用实例变量时的堆和堆栈(Java 内存)
【发布时间】:2018-06-06 14:01:30
【问题描述】:
public class Main {
    private String sampleName= "Sample";
    public void show() {
        System.out.println(sampleName);
    }
}

我知道“Sample”作为对象位于堆部分,但“sampleName”作为参考变量在哪里?如果它位于堆中,是否在堆栈中我有另一个名为“sampleName”的引用,该引用在堆中引用“sampleName”?

【问题讨论】:

  • 引用变量作为Main对象的一部分存在于堆中。
  • @shmosel 在 println 方法调用时,我们如何从堆栈帧访问“sampleName”引用?我认为 sampleName 作为参数的作用类似于局部变量并位于堆栈上。对吗?
  • 一旦作为参数传递,它就会被压入堆栈。

标签: java memory heap-memory stack-memory


【解决方案1】:

我知道“样本”作为对象位于堆部分

正确。

但是“sampleName”作为参考变量在哪里?

Main 对象中,根据定义,该对象位于堆中。

如果它位于堆中,是否在堆栈中我有另一个名为“sampleName”的引用,该引用在堆中引用“sampleName”

是的,作为println() 的参数的临时参数。

【讨论】:

    【解决方案2】:

    您的线程将只包含对封闭Main 对象的引用。它指向在堆中分配的Main 对象。 sampleName 引用是Main 对象的一个​​字段,因此也在堆上,指向字符串"Sample",该字符串保存在java 常量字符串池(堆中的另一个部分)中。堆栈上不能有 sampleName 引用,因为它是私有字段;否则,您将能够在 Main 类之外的代码中访问它,这违反了 java 语言语义。如果您将sampleName 字段定义为public,并且在您的代码中您做了

    Main main = new Main();
    String copyOfSampleName = main.sampleName;
    

    然后,您的堆栈上将有一个 String 引用,它与原始 sampleName 引用一起指向常量池中的 String 对象。

    【讨论】:

    • show 方法调用时,会自动创建一个新变量并放入堆栈,然后引用 sampleName 实例变量。是不是意思?
    • @Hamid 这不是发生的事情。那么sampleName 变量被当前线程通过Main 对象隐式引用,对吧?因此,当调用show 方法时,Main 的“this”引用将被传递到方法调用的堆栈帧,System.out.println(sampleName); 将在Main 对象的范围内执行。由于类内部可以访问私有字段,所以可以打印出sampleName的值。
    • 更详细的解释可能需要对 java 方法调用机制有更深入的了解。如果有兴趣,请阅读javaworld.com/article/2076949/learn-java/… 或类似材料。
    猜你喜欢
    • 1970-01-01
    • 2014-12-09
    • 2017-01-04
    • 1970-01-01
    • 2012-03-14
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    • 2016-08-13
    相关资源
    最近更新 更多