一个对象可以存储在堆栈而不是Java中的堆中吗?

use*_*_vs 12 java

对象可以存储在堆栈而不是堆中吗?

我最近浏览了这个博客 http://www.programmerinterview.com/index.php/data-structures/difference-between-stack-and-heap/

对象可以存储在堆栈而不是堆中吗?

是的,对象可以存储在堆栈中.如果在不使用"new"运算符的情况下在函数内创建对象,则会在堆栈上创建并存储对象,而不是在堆上.假设我们有一个名为Member的C++类,我们要为其创建一个对象.我们还有一个名为somefunction()的函数.这是代码的样子:

他们建议对象可以存储在Heap中.这令人困惑.

我以为,

  1. Java中的所有对象都存储在堆上.
    是否由
    a 创建.new Keyword
    湾 用Class.forName().
    c.用clone().
    d.使用newInstance()方法
    e.使用对象反序列化.

  2. 方法,线程和变量都在堆栈中.

  3. 类变量(静态变量)存储为与该类关联的Class对象的一部分.此Class对象只能由JVM创建,并存储在永久生成中.

如果我错了,请纠正我.

现在我怀疑对象是否可以以任何形式驻留或存储在堆栈中.

谢谢.

Rea*_*tic 6

您的观点(1):所有对象都在堆上分配。

这几乎是正确的。对象总是分配在堆上。然而,如果对象的转义分析允许(它仅对调用方法可见,并且不会转义到调用方法之外),则可以在堆栈上分配对象,如IBM 网站上的本文所述。

但请注意,Oracle在本技术说明中明确表示,由于其逃逸分析的结果,它不会用堆栈分配替换堆分配

所以是的,在 (Oracle) Java 中对象总是位于堆上。


你的观点(2):方法、线程和变量都在堆栈上。

不,方法和线程不在堆栈上。局部变量和参数放置在堆栈上。在每次方法调用时,都会准备一个堆栈帧,并在其中为参数、返回值和局部变量分配空间。

方法本身是类的一部分。线程对象的分配与任何其他对象一样,但线程本身不是数据,也不会分配,而是为它们分配堆栈。


您的观点 (3):静态变量是在 PermGen 上分配的。

此信息在 Java 8 之前都是正确的。根据JEP 122,它们现在分配在堆上,因为 PermGen 已被消除。

请注意,此类实现细节在 JVM 的不同实现之间是不同的。其他 JVM 甚至在 Java 8 之前就已经摆脱了 PermGen。


out*_*dev 5

所有类实例都存储在堆中.

以下是一些可靠的消息来源:
来自JVM规范:https :
//docs.oracle.com/javase/specs/jvms/se8/jvms8.pdf

2.5.3堆

Java虚拟机具有在所有Java虚拟机线程之间共享的堆.堆是运行时数据区,从中分配所有类实例和数组的内存.

来自Java语言规范: https :
//docs.oracle.com/javase/specs/jls/se8/jls8.pdf

17.4.1共享变量

可以在线程之间共享的内存称为共享内存或堆内存.所有实例字段,静态字段和数组元素都存储在堆内存中.


rgh*_*ome 2

您引用的注释是指 C++,它可以在堆栈上存储对象。在 Java 中,你不能。