虚拟机栈执行过程即栈帧随方法调用压入、随返回弹出:线程私有、自动管理、无需垃圾回收;方法调用时创建栈帧并入栈,含返回地址、局部变量表、操作数栈等;方法返回时弹出栈帧,恢复调用者状态;栈帧结构编译期固定,递归深度受-Xss限制;异常包括StackOverflowError和OutOfMemoryError。

虚拟机栈的执行过程,核心就是栈帧随方法调用而压入、随方法返回而弹出。这个过程是线程私有的、自动管理的,不依赖垃圾回收,也不受运行时变量值影响。
方法调用:栈帧入栈的完整步骤
每次方法被调用时,JVM会为它创建一个新栈帧,并将其压入当前线程的虚拟机栈顶:
- 先在调用方栈帧中保存返回地址(即调用指令的下一条字节码位置)
- 根据方法的 Code 属性,确定该栈帧所需的局部变量表大小和操作数栈深度
- 将参数从左到右(Java 字节码按从左到右顺序加载参数,但实际入栈顺序由调用约定决定)复制进新栈帧的局部变量表
- 设置动态链接,指向运行时常量池中该方法的符号引用
- 栈帧成为新的“当前栈帧”,执行引擎开始执行其字节码
方法返回:栈帧出栈的关键条件
方法结束执行时,无论正常 return 还是抛出未捕获异常,都会触发栈帧弹出:
- 若方法有返回值,该值会被暂存在调用方栈帧的操作数栈顶部,供后续使用
- 当前栈帧整个结构被销毁,内存直接释放(无 GC 参与)
- 控制权交还给前一个栈帧,执行引擎继续从保存的返回地址处执行
- 原调用方栈帧重新成为“当前栈帧”,恢复其局部变量表和操作数栈状态
栈帧结构决定执行边界
每个栈帧不是运行时动态分配任意空间,而是编译期就固定了结构尺寸:
- 局部变量表大小、操作数栈最大深度,都写在 class 文件的方法 Code 属性中
- 这意味着递归深度受限于栈容量(-Xss 参数),而非堆内存或变量内容
- 栈顶栈帧始终是唯一活跃的,其他栈帧仅保存上下文,不参与当前指令执行
- 线程终止时,整个虚拟机栈连同所有残留栈帧一并销毁
常见异常与栈行为的关系
两类典型错误直接反映栈的物理限制:
- StackOverflowError:单个线程调用链过深,栈空间耗尽,无法再分配新栈帧
- OutOfMemoryError(unable to create new native thread):全局线程数过多,各线程的-Xss总和超出系统内存,导致无法创建新栈

















