对象是否可以存储在堆栈而不是堆中?
我最近浏览了这个博客 http://www.programmerinterview.com/index.php/data-structures/difference-between-stack-and-heap/
对象是否可以存储在堆栈而不是堆中?
是的,对象可以存储在堆栈中。如果在不使用“new”运算符的情况下在函数内创建对象,则会在堆栈上创建并存储对象,而不是在堆上。假设我们有一个名为Member的C ++类,我们要为其创建一个对象。我们还有一个名为somefunction()的函数。这是代码的样子:
他们建议对象可以存储在Heap中。这令人困惑。
我想到了,
Java中的所有对象都存储在堆中
是否由
创建
一个。 new Keyword
湾使用Class.forName().
C。使用clone().
d。使用newInstance()
方法
即使用对象反序列化。
方法,线程和变量都在堆栈中。
如果我错了,请纠正我。
现在我怀疑对象是否可以以任何形式驻留或存储在堆栈中。
谢谢。
答案 0 :(得分: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共享变量
可以在线程之间共享的内存称为共享内存或 堆内存。所有实例字段,静态字段和数组元素 存储在堆内存中。
答案 1 :(得分:3)
您的观点(1):所有对象都在堆上分配。
这是非常正确的。对象始终在堆上分配。但是,如果对象可以在其堆栈上进行转义分析(它只对调用方法可见,并且不会在其外部转义),则可以在堆栈上分配 ,如{{3}中所述。在IBM网站上。
但请注意,Oracle明确表示,由于this article中的转义分析,它确实 用堆栈分配替换堆分配。
所以,是的,对象总是在(Oracle)Java中的堆上。
您的观点(2):方法,线程和变量在堆栈中。
不,方法和线程不在堆栈中。局部变量和参数放在堆栈上。在每次方法调用时,都会准备一个堆栈帧,并在其中为参数,返回值和局部变量分配空间。
方法本身是课程的一部分。线程对象的分配方式与任何其他对象一样,但线程本身不是数据,也没有分配,而是为它们分配堆栈。
您的观点(3):静态变量在PermGen上分配。
这个信息在Java 8之前是正确的。根据this technical note,它们现在被分配在堆上,因为PermGen已被淘汰。
请注意,JVM的不同实现之间的此类实现细节是不同的。其他JVM甚至在Java 8之前就已经摆脱了PermGen。
答案 2 :(得分:2)
必须在堆中分配所有Java对象:
[...]堆是运行时数据区,所有类的内存 实例和数组已分配
但是,由于escape analysis,某些对象可能会优化为基本类型并存储在堆栈中。在这种情况下,他们从未真正成为对象,因此并没有真正违反规则。