【问题标题】:Do Java primitives go on the Stack or the Heap?Java原语是在堆栈还是堆上?
【发布时间】:2011-04-08 11:30:31
【问题描述】:

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

--更新

根据答案,我可以说堆可以有一个给定对象的新堆栈和堆?鉴于该对象将具有原始变量和引用变量..?

【问题讨论】:

  • 每个线程都有自己的栈,而不是每个对象。如果只有一个线程,那么只有一个堆栈。

标签: java heap-memory stack-memory


【解决方案1】:

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

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 在堆栈上,因为它是在方法体中声明的,而不是作为类的成员。

【讨论】:

  • 如果你仔细想想,这是完全合理的,因为局部变量的词法范围将决定何时需要将其从堆栈中删除。 :-)。当一个对象准备好垃圾时间时,整个事情都必须完成。不过,我总是对类的静态成员有问题。我不记得这些值去了哪里。假设int y 是静态成员:-P
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    在这两个地方都可以找到原语。

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

    关于更新:

    栈和堆的区别不是存储在其中的内容,而是为它们提供的操作。堆栈允许您以 LIFO 方式分配一块内存,直到所有比它年轻的块也都被释放后,您才能释放一块内存。这方便地与调用堆栈的使用方式保持一致。您可以将任何东西放在堆栈上,只要在您的函数返回时该东西可以消失即可。这是一种优化,因为它只支持以这种方式使用,所以从堆栈中分配和解除分配非常快。如果愿意,可以在实现中将函数的所有局部变量存储在堆上。堆更灵活,因此使用成本更高。说一个对象有栈和堆是不准确的,就像我说的,栈和堆的区别不是它里面有什么,而是可用的操作。

    【讨论】:

    • @Logan: // f.x is probably on the heap -> 你是说这取决于JVM的实现吗?
    【解决方案4】:

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

    【讨论】:

    • 当我将原语从一个对象传递给另一个对象的方法时,局部变量总是进入堆栈,对吗? (即使方法是静态的)
    猜你喜欢
    • 2010-11-06
    • 2016-12-27
    • 2021-10-13
    • 2011-10-07
    • 2015-05-03
    • 2019-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多