堆内存中数据更改的值?

Value of data change inside the heap memory?

提问人:Koushik Andhavarapu 提问时间:7/16/2022 更新时间:7/16/2022 访问量:309

问:

因此,我试图弄清楚数据中的值如何相应地变化。我已经对我所理解的内容写了评论。任何人都可以解释一下如何存储在堆和堆栈内存中的值来解决这个问题。

public class CBV
{
    static int data = 10;
    public static void main(String []args)
    {
        // data is a local variable
        //int data = 10;
        System.out.println("Before data: "+data);
        changeData(data);
        System.out.println("After data: "+data);
    }
    public static void changeData(int data)
    {
        // data is changed and its scope is within this method
        // so the original value is not changed
        // In java, garbage collection is automatically handled
        data = data + 500;
        // so  here data is garbage collected
    }
}
Java 内存 按值调用

评论

0赞 Louis Wasserman 7/16/2022
垃圾回收甚至不会发生在像 .int

答:

0赞 ControlAltDel 7/16/2022 #1

只有对象在堆上。并且(除了自动装箱)对象是使用运算符创建的。new

因此,在您的示例中,CBV 的类对象(包括其静态数据字段)位于堆上(但永远不会被垃圾回收,因为它不是动态加载的)。在 changeData 中,位于堆栈上data

0赞 Tintin 7/16/2022 #2

您需要了解堆栈和堆之间的区别。或者更好的是,你需要了解 Java 的内存模型和一些关于垃圾回收的知识(最后添加了资源)。

关于这个主题有很多需要解释的地方,这个线程永远不够。但对于您的特定问题,这里存在 2 个上下文。data

  • 作为类数据(在本例中为静态变量) - 它被存储在堆中(见下面的说明)。由于这是一个静态属性,因此只要加载了类本身,它就会保留在内存中。另一方面,如果这是一个非静态字段,它将与每个类实例单独存在。只有当相应的对象本身被垃圾收集时,它对应的每个副本的相应内存才会被回收。CBV
  • 作为方法的方法参数 - 它存储在堆栈中,并在方法执行结束后立即超出范围(请参阅下面的说明)changeData

stackoverflow 上的这个答案

  • 如果一个变量打算在创建后不久就超出范围 - 例如,在创建它的方法结束时,甚至更早,那么在堆栈上创建该变量是合适的。局部变量和方法参数符合此标准;如果它们是基元,则实际值将位于堆栈上,如果它们是对象,则对对象(但不是对象本身)的引用将位于堆栈上。

  • 如果某个变量的寿命比创建它的方法的执行时间长,则该变量需要位于堆上。这既适用于您创建的任何对象,也适用于存储在这些对象中的任何基元。

垃圾回收仅触发动态创建的对象,即使用运算符(它们始终存储在堆中)。new

如果您是新手,这些解释可能会有点令人困惑,因此我建议您先浏览下面提到的这些文献。

其他一些资源

  1. 了解 Java 内存模型 - 它讨论了对象分配垃圾回收
  2. Java 虚拟机的结构