Java 中的堆栈与堆

2025年3月26日 | 阅读 3 分钟

在 Java 中,内存管理是一个至关重要的过程。它由 Java 自动管理。JVM 将内存分为两部分:堆栈内存和内存。从 Java 的角度来看,两者都是重要的内存区域,但用途不同。堆栈内存和堆内存之间的主要区别在于,堆栈用于存储方法执行的顺序和局部变量,而堆内存用于存储对象,并且它使用动态内存分配和释放。在本节中,我们将详细讨论堆栈和堆之间的区别。

Stack Vs Heap Java

堆栈内存

堆栈内存是运行时分配给每个线程的物理空间(在 RAM 中)。它在线程创建时创建。堆栈中的内存管理遵循 LIFO(后进先出)顺序,因为它全局可访问。它存储变量、对象引用和中间结果。分配给堆栈的内存直到函数返回为止。如果没有空间创建新对象,则会抛出 java.lang.StackOverFlowError。元素的范围仅限于其所在的线程。JVM 为每个线程创建一个单独的堆栈。

堆内存

它在 JVM 启动时创建,并在应用程序运行时一直被应用程序使用。它存储对象和 JRE 类。每当我们创建对象时,它都会占用堆内存空间,而该对象的引用则在堆栈中创建。它不遵循任何像堆栈那样的顺序。它动态处理内存块。这意味着我们不必手动处理内存。为了自动管理内存,Java 提供了垃圾回收器,用于删除不再使用的对象。分配给堆的内存直到发生任一事件才会消失:程序终止或内存释放。元素在应用程序中全局可访问。它是所有线程共享的通用内存空间。如果堆空间已满,则会抛出 java.lang.OutOfMemoryError。堆内存进一步划分为以下内存区域:

  • 年轻代
  • 幸存区
  • 老年代
  • 永久代
  • 代码缓存

下图显示了堆栈内存和堆空间的分配。

Stack Vs Heap Java

堆栈内存与堆内存的区别

下表总结了堆栈内存和堆空间之间所有的主要区别。

参数堆栈内存堆空间
应用它存储生命周期非常短的项,例如方法、变量和对象的引用变量它存储对象和 Java 运行时环境 (JRE) 类。
排序它遵循LIFO 顺序。它不遵循任何顺序,因为它是动态内存分配,并且在内存块的分配和释放方面没有固定模式。
灵活性不灵活,因为我们无法更改已分配的内存。灵活,因为我们可以更改已分配的内存。
效率它的访问、分配和释放更快它的访问、分配和释放较慢
内存大小它的大小较小它的大小较大
使用的 Java 选项我们可以使用 JVM 选项 -Xss 来增加堆栈大小。我们可以使用 -Xmx 和 -Xms JVM 选项来增加或减小堆内存大小。
可见性或范围变量仅对所有者线程可见。对所有线程可见。
空间生成当线程创建时,操作系统会自动分配堆栈。要为应用程序创建堆空间,语言首先在运行时调用操作系统。
分发为每个对象创建一个单独的堆栈。所有线程共享。
异常抛出如果堆栈大小超过限制,JVM 会抛出java.lang.StackOverFlowError。为避免此错误,请增加堆栈大小。如果 JVM 无法创建新的本地方法,则会抛出java.lang.OutOfMemoryError
分配/释放编译器自动完成。程序员手动完成。
费用它的成本较低与堆栈相比,它的成本更高
实施它的实现困难它的实现简单
分配顺序内存分配是连续的。内存以随机顺序分配。
线程安全它是线程安全的,因为每个线程都有自己的堆栈。它不是线程安全的,因此需要对代码进行适当的同步。