Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java原语是放在堆栈上还是堆上?_Java_Stack_Heap - Fatal编程技术网

Java原语是放在堆栈上还是堆上?

Java原语是放在堆栈上还是堆上?,java,stack,heap,Java,Stack,Heap,我只知道非原语(对象)放在堆上,方法放在堆栈上,但是原语变量呢 --更新 根据答案,我可以说堆可以有一个新的堆栈,对于给定的对象堆?假设对象将有基元变量和引用变量。所有局部变量(包括方法参数)都将放在堆栈上;对象及其所有字段都存储在堆中。变量始终是基本体或对对象的引用 Java实现实际上可以在堆上存储对象,这样它仍然符合规范。类似地,局部变量可能存储在寄存器中,或者通过优化变得模糊。在这两个地方都可以找到基本变量 class Foo { public int x; public st

我只知道非原语(对象)放在堆上,方法放在堆栈上,但是原语变量呢

--更新

根据答案,我可以说堆可以有一个新的堆栈,对于给定的对象堆?假设对象将有基元变量和引用变量。

所有局部变量(包括方法参数)都将放在堆栈上;对象及其所有字段都存储在堆中。变量始终是基本体或对对象的引用


Java实现实际上可以在堆上存储对象,这样它仍然符合规范。类似地,局部变量可能存储在寄存器中,或者通过优化变得模糊。

在这两个地方都可以找到基本变量

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,也永远不会传递给另一个函数,所以在堆栈上分配它是安全的

关于更新:


堆栈和堆的区别不在于它们存储了什么,而在于为它们提供的操作。堆栈允许您以后进先出的方式分配内存块,在所有比它年轻的内存块都被释放之前,您无法释放内存块。这方便地与调用堆栈的使用方式保持一致。您可以在堆栈上放置任何内容,只要在函数返回时该内容可以消失。这是一种优化,因为从堆栈分配和取消分配非常快,因为它只支持以这种方式使用。如果需要,可以将一个函数的所有局部变量存储在一个实现的堆中。堆更灵活,因此使用成本更高。说一个对象有一个堆栈和一个堆是不准确的,正如我所说的,区别堆栈和堆的不是堆栈中的内容,而是可用的操作。

本地定义的原语将位于堆栈上。但是,如果将原语定义为对象实例的一部分,则该原语将位于堆上

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.
    }
}
关于更新:

对象没有自己的堆栈。在我的示例中,
inty
实际上是
HeapClass
的每个实例的一部分。每当分配HeapClass的实例时(例如,
new Test.HeapClass()
),HeapClass的所有成员变量都会添加到堆中。因此,由于
HeapClass
的实例是在堆上分配的,
int y
将作为
HeapClass
实例的一部分在堆上

但是,在任何方法体中声明的所有基本变量都将在堆栈上


正如您在上面的示例中所看到的,
int x
位于堆栈上,因为它是在方法体中声明的,而不是作为类的成员声明的。

原语值在堆栈上分配,除非它们是对象的字段,在这种情况下,它们位于堆上。堆栈用于求值和执行,所以说具有基本字段的对象有一个堆栈是没有意义的,因为它仍然被认为是堆的一部分。甚至
Stack
对象也在堆上分配。

如果您仔细想想,这是非常有意义的,因为局部变量的词法范围将决定何时需要从堆栈中删除它。:-。当一个对象为垃圾时间做好准备时,整个过程必须进行。不过,我在处理类的静态成员时总是遇到麻烦。我不记得这些价值观去了哪里。假设
inty
是静态成员:-PEach线程有自己的堆栈,而不是每个对象。如果只有一个线程,那么就只有一个堆栈。@Logan:
//f.x可能在堆上
->你是说它取决于JVM实现吗?当我将原语从一个对象传递到另一个对象的方法时,局部变量总是在堆栈右边?(即使方法是静态的或非静态的)
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.
    }
}