Java原语是堆栈还是堆?
我只知道非基元(对象)在堆上,方法在堆栈上,但是基元variables呢?
–update
根据答案,我可以说堆可以有一个新的堆栈和堆给定的对象? 鉴于该对象将具有原始和参考variables..?
在本地定义的基元将在堆栈上。 然而,如果一个原语被定义为一个对象实例的一部分,那么这个原语将会在堆上。
public class Test { private static class HeapClass { public int y; // When an instance of HeapClass is allocated, this will be on the heap. } public static void main(String[] args) { int x=1; // This is on the stack. } }
关于更新:
对象没有自己的堆栈。 在我的例子中, int y
实际上是HeapClass
的每个实例的HeapClass
。 每当HeapClass的实例被分配时(例如new HeapClass()
),HeapClass的所有成员variables都被添加到堆中。 因此,由于HeapClass
实例正在堆中分配,因此int y
将作为HeapClass
实例的一部分放在堆上。
但是,任何方法的主体中声明的所有基本variables都将在堆栈中。
正如你在上面的例子中看到的那样, int x
在堆栈中,因为它是在方法体中声明的 – 而不是类的成员。
所有局部variables(包括方法参数)都在堆栈上; 对象和所有的字段都存储在堆中。 variables始终是对象的基元或引用 。
Java实现可能实际上将对象存储在堆上,使得它仍然符合规范。 类似地,局部variables可以被存储在寄存器中,或者通过优化变得模糊不清。
在两个地方都可以find基元。
class Foo { public int x; public static void Main() { int y = 3; // y is on the stack Foo f = new Foo(); // fx is probably on the heap } }
除非你正在构build一个JVM,否则你不应该在乎。 一个非常聪明的优化器可能会决定,因为F指出永远不会逃脱Main,并且永远不会传递给另一个函数,因此在堆栈上分配它是安全的。
关于更新:
堆栈和堆不是由它们中存储的内容来区分的,而是为它们提供的操作。 该堆栈允许您以LIFO方式分配一块内存,直到所有比它小的块都被释放,才能释放一块。 这很方便地与如何使用调用堆栈alignment。 你可以把任何东西放在堆栈上,只要这个东西在你的函数返回的时候离开就可以了。 这是一个优化,因为它只支持以这种方式使用,所以从堆栈中分配和释放非常快。 如果需要的话,可以在一个实现中将一个函数的所有局部variables存储在堆中。 堆更灵活,因此使用起来更昂贵。 如我所说,一个对象有一个堆栈和一个堆是不正确的,但是堆栈和堆的区别不在于它是什么,而是可用的操作。
原始值在堆栈上分配,除非它们是一个对象的字段,在这种情况下,它们将在堆上。 堆栈用于评估和执行,所以不能说具有原始字段的对象具有堆栈 – 它仍然被认为是堆的一部分。 即使Stack
对象也被分配在堆上。