JVM 在哪里存储基元变量?

2022-09-01 15:13:49

Java JVM 在哪里存储基元变量,原语在使用后如何使用内存?

我猜它在堆栈上?


答案 1

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

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

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

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

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

class Foo
{
    private int value;
    ...
}

从概念上讲,将作为 任何 实例的数据的一部分存在于堆上。它将作为释放实例的一部分被释放 - 它仅在表示实例的数据块内有4个字节;它不需要单独的解除分配。FooFoo


答案 2

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

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

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

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

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

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

String firstString = "Stack";
String secondString = "Stack";

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