目录

堆栈区别

# 堆(heap)和栈(stack)的区别

经常有人把 Java 的内存区域笼统的划分为堆内存 (Heap)和栈内存(Stack),这种划分方式继承自传统的 C 、C++ 程序的内存布局结构,在 Java 中实际的内存分配区域比这更复杂。”栈“通常指虚拟机栈,或者更多情况下只是指虚拟机栈中的局部变量表部分。

局部变量表存放了编译期间可知的各种 Java 虚拟机的基本数据类型 (boolean、byte、char、short、int、float、long、double)、对象引用和 returnAddress 类型(指向了一条字节码指令的地址)。

这些数据类型在局部变量表中的存储空间以局部变量槽(Slot)来表示,其中 64 位的 long 和 double 类型的数据会占用两个变量槽,其余的数据类型只占用一个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量的大小。这里说的“大小”是指变量槽的数量,虚拟机真正使用多大的内存空间(例如按照 1 个变量槽占用 32 个bit、64 个bit,或者更多)来实现一个变量槽,这是由虚拟机实现自行决定的事情。

# 堆:

  • 线程共享,整个 Java 虚拟机只有一个堆,堆是所有线程共享的。

  • 异常错误 java.lang.OutOfMemoryError

  • 通过 -Xms 选择配置堆的开始时大小,-Xmx 配置堆的最大值

  • 堆分配可以处于物理上不连续的空间,但在逻辑上它应该被视为连续的。但对于大对象(典型的如数组对象),多数虚拟机实现处于实现简单、存储高效的考虑,很可能要求连续内存空间。

#

  • 每个线程独享栈空间

  • 异常错误 java.lang.StackOverFlowError,每次调用方法都会生成一个栈帧,当函数调用链很长时,生成的栈帧大小超过设定栈总内存,就会溢出产生 StackOverFlowError 错误。

  • 栈空间远远小于堆空间,可以通过 -Xss 选项配置栈内存大小,栈的内存分配是连续的。

  • 存储的是基本数据类型、对象引用 和 returnAddress 类型

#

上次更新: 2024/11/05, 03:15:29