JVM在哪里存储原始变量?

时间:2010-09-13 05:55:21

标签: java memory-management jvm

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

我猜它在堆栈上?

3 个答案:

答案 0 :(得分:37)

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

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

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

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

从概念上来说这个模型是准确的。所以类型int的变量被声明为实例变量,如下所示:

class Foo
{
    private int value;
    ...
}

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

答案 1 :(得分:5)

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

本地变量存储在堆栈中。 实例静态变量存储在上。

让我用一个例子解释一下。假设我们有一个自定义类Animal的实例变量动物。     动物动物=新狗(); 动物只是参考,位于堆栈。实际对象在上分配内存。此引用动物将指向在堆上分配的此对象内存。因此,如果您有3个引用指向同一个对象。

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

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

当我们存储基本类型或字符串文字时,存在轻微的变化。除非使用new()运算符显式创建对象,否则它们将被创建并存储在Heap的 permGen 区域中。 所以两者都引用了

中的firstString和secondString
String firstString = "Stack";
String secondString = "Stack";

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

答案 2 :(得分:4)

  • 类对象,包括方法代码和静态字段:heap。
  • 对象,包括实例字段:heap。
  • 局部变量和对方法的调用:stack ..