我只知道非原语(对象)放在堆上,方法放在堆栈上,但是原生变量呢?
--更新
根据答案,我可以说堆可以有一个新的堆栈和给定对象的堆?假设对象将具有基元变量和引用变量..?
发布于 2010-09-05 23:56:12
本地定义的原语将位于堆栈上。但是,如果将原语定义为对象实例的一部分,则该原语将位于堆中。
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 Test.HeapClass()
),HeapClass的所有成员变量都会添加到堆中。因此,由于HeapClass
的实例是在堆上分配的,因此int y
将作为HeapClass
实例的一部分在堆上。
但是,在任何方法的主体中声明的所有原始变量在堆栈上都是。
正如您在上面的示例中看到的,int x
之所以在堆栈上,是因为它是在方法体中声明的--而不是作为类的成员。
发布于 2010-09-05 23:52:17
所有局部变量(包括方法参数)都放在堆栈中;对象及其所有字段都存储在堆中。变量始终是基本类型或对对象的引用。
Java实现可能实际上将对象存储在堆上,以使其仍然符合规范。类似地,局部变量可以存储在寄存器中,或者通过优化而变得模糊不清。
发布于 2010-09-05 23:52:54
在这两个地方都可以找到原语。
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指向的Foo永远不会转义Main,并且永远不会传递给另一个函数,所以在堆栈上分配它是安全的。
关于更新:
堆栈和堆的区别不在于存储在其中的内容,而在于为它们提供的操作。堆栈允许你以后进先出的方式分配一块内存,你不能释放一块内存,直到所有比它更年轻的内存块也被释放。这很方便地与调用堆栈的使用方式一致。你可以把任何东西放在堆栈上,只要当你的函数返回时,那个东西消失了就行了。这是一种优化,因为它从堆栈中分配和释放非常快,因为它只支持以这种方式使用。如果需要的话,可以在实现中存储堆中函数的所有局部变量。堆更灵活,因此使用成本也更高。正如我所说的,说一个对象有一个堆栈和一个堆是不准确的,堆栈与堆的区别不是它里面有什么,而是可用的操作。
https://stackoverflow.com/questions/3646632
复制相似问题