Java JVM在哪里存储原始变量,以及原语在使用后释放的内存是如何释放的?
我猜它在堆栈上?
答案 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和secondStringString firstString = "Stack";
String secondString = "Stack";
将指向String池中的同一对象。当我们使用new()创建它们时,它会指向不同的对象。
答案 2 :(得分:4)