【发布时间】:2011-04-11 12:23:26
【问题描述】:
Java JVM 在哪里存储原语变量,原语使用的内存在使用后如何释放?
我猜它在堆栈上?
【问题讨论】:
标签: java memory-management jvm
Java JVM 在哪里存储原语变量,原语使用的内存在使用后如何释放?
我猜它在堆栈上?
【问题讨论】:
标签: java memory-management jvm
变量的存储位置取决于变量是局部变量还是实例变量。
本地变量存储在堆栈中。 Instance 和 static 变量存储在 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和secondStringString firstString = "Stack";
String secondString = "Stack";
将指向字符串池中的同一个对象。当我们使用 new() 创建对象时,它会指向不同的对象。
【讨论】:
Dog 对象时的一个小错误。三个不同的Animal 引用指向三个不同的对象。
【讨论】:
简单的回答:这取决于变量的声明位置,而不是其类型。
局部变量存储在堆栈中。实例和静态变量存储在堆上。
不要忘记,对于引用类型的变量,变量的值是引用,而不是对象。 (数组也是引用类型 - 所以如果你有一个 int[],值将在堆上。)
现在,这可能是一个过于简单化的答案,因为智能 VM 可能能够检测特定引用类型变量是否引用了永远无法“逃脱”当前方法的对象。如果是这种情况,它可能会将整个对象内联到堆栈中。
但是在概念上这个模型是准确的。所以int 类型的变量被声明为这样的实例变量:
class Foo
{
private int value;
...
}
在概念上将作为Foo 任何实例的数据的一部分存在于堆上。它将作为释放实例的一部分被释放 - 它只是代表Foo 实例的数据块中的 4 个字节;它不需要单独的释放。
【讨论】: