【问题标题】:Where does the JVM store primitive variables?JVM 在哪里存储原始变量?
【发布时间】:2011-04-11 12:23:26
【问题描述】:

Java JVM 在哪里存储原语变量,原语使用的内存在使用后如何释放?

我猜它在堆栈上?

【问题讨论】:

    标签: java memory-management jvm


    【解决方案1】:

    变量的存储位置取决于变量是局部变量还是实例变量

    本地变量存储在堆栈中。 Instancestatic 变量存储在 heap 上。

    让我用一个例子来解释一下。假设我们有一个自定义类 Animal 的实例变量 animal。 动物 动物 = new Dog(); 这里的animal 只是一个reference,它位于stack 上。实际对象在 heap 上分配内存。这个引用动物将指向在堆上分配的这个对象内存。所以如果你有 3 个引用指向同一个对象。

    Animal animal1 = new Dog();
    Animal animal2 = new Dog();
    Animal animal3 = new Dog();
    

    所有三个引用都将在堆栈中。当我说引用时,它只是指向堆上对象的指针。在内存方面,这个引用保存了堆上对象的地址(实际上这里没有更多的抽象)。所以 32 位 4 个字节和 64 位 8 个字节。只有当所有三个引用都被取消引用,即它们不再在范围内(或者更确切地说不再指向原始对象)时,只有垃圾收集器才能释放分配给堆上对象的内存.

    当我们存储原始类型或字符串字面量时会有细微的变化。除非您使用 new() 运算符显式创建它们的对象,否则它们将被创建并存储在堆的 permGen 区域中。 所以在

    中都引用了firstString和secondString
    String firstString = "Stack";
    String secondString = "Stack";
    

    将指向字符串池中的同一个对象。当我们使用 new() 创建对象时,它会指向不同的对象。

    【讨论】:

    • 在谈论Dog 对象时的一个小错误。三个不同的Animal 引用指向三个不同的对象。
    【解决方案2】:
    • 类对象,包括方法代码和静态字段:堆。
    • 对象,包括实例字段:堆。
    • 局部变量和方法调用:堆栈..

    【讨论】:

      【解决方案3】:

      简单的回答:这取决于变量的声明位置,而不是其类型。

      局部变量存储在堆栈中。实例和静态变量存储在堆上。

      不要忘记,对于引用类型的变量,变量的值是引用,而不是对象。 (数组也是引用类型 - 所以如果你有一个 int[],值将在堆上。)

      现在,这可能是一个过于简单化的答案,因为智能 VM 可能能够检测特定引用类型变量是否引用了永远无法“逃脱”当前方法的对象。如果是这种情况,它可能会将整个对象内联到堆栈中。

      但是在概念上这个模型是准确的。所以int 类型的变量被声明为这样的实例变量:

      class Foo
      {
          private int value;
          ...
      }
      

      在概念上将作为Foo 任何实例的数据的一部分存在于堆上。它将作为释放实例的一部分被释放 - 它只是代表Foo 实例的数据块中的 4 个字节;它不需要单独的释放。

      【讨论】:

      • Java 对原始变量和非原始变量的处理不同吗?
      • 数组内容也在堆中。我会说“除了捕获的变量之外的局部变量”,但我刚刚阅读了您关于 Java 和 C# 闭包之间区别的文章,我猜 Java 中没有捕获的 variable 这样的东西。在 C# 中,对于局部变量(除非被捕获)和堆栈中的值类型成员以及数组内容和引用类型成员的堆,它都位于堆栈上。
      • @Ben:是的,将添加关于数组的内容,尽管严格来说已经涵盖了,因为数组是引用类型。在 C# 中,您需要覆盖迭代器块中的局部变量,这也将在堆上。
      • @JRomio:所有局部变量要么是内置类型,要么是指向用户定义类型的句柄(Java 称之为引用,但实际上它实际上是一个指针),两者都是原始。只有指向的 UDT 是非原始的,但这与持有句柄的变量不同。
      • @Ben:在那种情况下,我根本不会称它为变量。我没有说明堆中的 everything 是实例或静态变量。无论如何,澄清后肯定会更好,所以谢谢:) @Rakesh:是的,数组是引用类型。您是否认为每次执行分配时都会复制数组的全部内容?
      猜你喜欢
      • 2017-03-26
      • 2010-10-02
      • 1970-01-01
      • 2018-02-01
      • 2010-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多