我只知道非基元(对象)放在堆上,而方法放在堆栈上,但是基元变量呢?Java基元是在栈还是在堆上?
--update
基础上的答案,我可以说堆能有一个给定对象的新栈和堆?鉴于该对象将有原始和参考变量..?
我只知道非基元(对象)放在堆上,而方法放在堆栈上,但是基元变量呢?Java基元是在栈还是在堆上?
--update
基础上的答案,我可以说堆能有一个给定对象的新栈和堆?鉴于该对象将有原始和参考变量..?
本地定义的原语将在堆栈中。然而,如果一个基元被定义为一个对象的一个实例的一部分,那么这个基元就会在堆上。
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实例(例如new HeapClass()
)时,HeapClass的所有成员变量都会添加到堆中。因此,由于HeapClass
的实例正在堆中分配,所以int y
将作为HeapClass
的实例的一部分堆在堆上。
但是,在任何方法的主体中声明的所有基元变量都将在堆栈中。
正如您在上面的示例中看到的,int x
在堆栈中,因为它在方法体中声明 - 而不是作为类的成员。
+1谢谢!请考虑我对该问题的新更新。 – 2010-09-05 16:00:28
您可能想要更改代码中的注释。在文本中,你说'x'在堆栈上,但注释表示堆。 – musiKk 2010-09-05 16:58:44
好的。谢谢。 – 2010-09-05 19:35:59
所有局部变量(包括方法参数)都在栈上;对象及其所有字段都存储在堆中。变量总是原语或引用到对象。
Java实现可能实际上将对象存储在堆上,使得它仍然符合规范。同样,局部变量可以存储在寄存器中,或者通过优化变得模糊不清。
+1谢谢!请考虑我对该问题的新更新。 – 2010-09-05 15:59:50
可以在两处找到基元。
class Foo
{
public int x;
public static void Main()
{
int y = 3; // y is on the stack
Foo f = new Foo(); // f.x is probably on the heap
}
}
除非你不应该真正关心,除非你正在构建一个JVM。一个非常聪明的优化器可能会决定,因为F指出永远不会转义Main,并且永远不会传递给另一个函数,因此可以安全地将其分配到堆栈上。
至于更新:
的栈和堆不受什么是存储在其中,但为他们提供相当的操作区别开来。该堆栈允许您以LIFO方式分配一块内存,直到所有比它年轻的块都被释放为止,您无法取消分配一块。这很方便地与调用堆栈的使用方式一致。只要你的函数返回时,你可以把任何东西放在堆栈上。这是一个优化,因为它只支持以这种方式使用,所以从堆栈中分配和释放非常快。如果需要,可以在实现中将函数的所有局部变量存储在堆中。堆更灵活,因此使用起来更昂贵。如我所说,一个对象有一个堆栈和一个堆是不正确的,但是堆栈和堆的区别并不在于它是什么,而是可用的操作。
+1谢谢!请考虑我对该问题的新更新。 – 2010-09-05 16:01:03
@logan:''f.x可能在堆上 - >你是说它取决于JVM的实现吗? – realPK 2017-03-10 16:34:41
原始值在堆栈上分配,除非它们是一个对象的字段,在这种情况下,它们将放在堆上。堆栈用于评估和执行,因此不要说具有原始字段的对象具有堆栈 - 它仍被认为是堆的一部分。即使Stack
对象也被分配在堆上。
每个线程都有自己的堆栈,而不是每个对象。如果只有一个线程,那么只有一个栈。 – Alex 2016-10-29 01:45:59