如果我使用Deque<Integer> stack = new LinkedList<Integer>();
在java方法中创建堆栈,为什么此堆栈变量存储在堆中而不存储在堆栈中?
答案 0 :(得分:5)
Java运行时使用Java堆空间为Objects和JRE类分配内存。每当我们创建任何对象时,它总是在堆空间中创建。
垃圾收集在堆内存上运行,以释放没有任何引用的对象使用的内存。在堆空间中创建的任何对象都具有全局访问权限,并且可以从应用程序的任何位置进行引用。
Java堆栈内存用于执行线程。它们包含短期的特定于方法的值以及对从该方法引用的堆中其他对象的引用。
堆栈内存始终按LIFO(后进先出)顺序引用。每当调用方法时,都会在堆栈存储器中创建一个新块,用于保存该方法的本地基本值并引用该方法中的其他对象。
方法结束时,该块将立即变为未使用状态,并可供下一个方法使用。 与堆内存相比,堆栈内存的大小要小得多。
因此,当您使用Deque stack = new LinkedList<>()
时,Deque stack
是根据数据模型堆栈的,但是根据JVM,这是仅仅是另一个对象,例如new Object()
,{ {1}}等。这些对象存储在堆中。
答案 1 :(得分:0)
诸如C
之类的某些语言允许您选择是在堆栈还是在堆上分配内存。有许多吸引人的原因,为什么您想使用堆栈。当“弹出”堆栈帧(函数返回)时,将自动free
d分配在堆栈上的内存。您还可以获得更好的性能,因为堆栈是连续的内存块,而内存可以分配到堆上的任何位置。编译器更容易优化。
但是,就像C
的许多方面一样,这里还有龙。线程安全或共享数据是不可能的。无论您在堆栈上分配的内容是什么,都不一定会超出函数调用的寿命。函数返回时,将释放堆栈上的对象,因此,如果需要从函数返回对象,则必须在堆上分配该对象。
堆栈分配可能很危险,并且需要对程序的内存使用情况有较低的了解。这些违反了Java的设计原则,即您应该能够让计算机为您处理内存管理。因此,语言设计师只是决定不让您这样做。由于Oleg已经共享了,所以在Java中,所有对象都分配在堆上。