与PC寄存器一样,Java虚拟机栈也是线程私有的。每一个JVM线程都有自己的java虚拟机栈,这个栈与线程同时创建,它的生命周期与线程相同。

1.虚拟机栈的特点

“虚拟机栈”描述的是Java方法执行的内存模型:

  1. 每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储:局部变量表操作数栈动态链接方法出口等信息。(栈帧我的理解就是一个对象,用来存储信息用)
  2. 每一个方法被调用直至执行完成的过程就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

局部变量表

  1. 存放了8种基本数据 类型
  2. 对象引用 类型
  3. returnAddress 类型

除64位 long 和 duble 占2个局部空间外,其余的数据类型只占1个。
注意,局部变量表所需的内存空间在编译期间完成分配,所以进入某个方法时,这个方法需要在栈桢中分配多大的空间完全是确定的,在方法运行时是不会改变局部变量表的大小的。

3.虚拟机栈出现异常两种情况

  1. 如果线程请求的深度大于虚拟机所允许的深度,将抛出 StackOverflowError 异常;
  2. 如果虚拟机进行动态扩展,而扩展时无法申请到足够的内存,则抛出 OutOfMemoryError 异常。

注,大部分 Java 虚拟机分为:固定长度动态扩展 两种

关于动态扩展

JVM stack 可以被实现成固定大小,也可以根据计算动态扩展。
如果采用固定大小的JVM stack设计,那么每一条线程的JVM Stack容量应该在线程创建时独立地选定。
JVM实现应该提供调节JVM Stack初始容量的手段;如果采用动态扩展和收缩的JVM Stack方式,应该提供调节最大、最小容量的手段。

如果线程请求的栈深度大于虚拟机所允许的深度将抛出StackOverflowError;
如果JVM Stack可以动态扩展,但是在尝试扩展时无法申请到足够的内存时抛出OutOfMemoryError