JVM —— Java 虚拟机栈

  • Java 虚拟机栈 ( Java Virtual Machine Stacks,以下简称 JVMS ) 是线程 ( Thread ) 私有的,它的生命周期与 Thread 相同。JVMS 描述的是 Java 方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧 ( Stack Frame,以下简称 SF ) 用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用直至执行完成的过程,就对应着一个 SF 在 JVMS 中入栈到出栈的过程。
  • 不少人笼统地把局部变量表当作 JVMS,其实不然。局部变量表存放了编译期可知地各种数据类型 ( boolean、byte、char、short、int、float、long、double )、对象引用 ( reference 类型 ) 和 returnAddress 类型。其中 long 和 double 会占用 2 个局部变量空间 ( Slot ),其余的数据类型占用 1 个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在 SF 中分配多大的局部变量空间时完全确定的,在方法运行期间不会改变局部变量表的大小。
  • 至于为什么叫栈帧?笔者猜测:帧,有量词之意,且网络之间的传输单位也称作 " 帧 ",因此,这里将栈帧看作一个基本单位。
  • 接下来测试一下栈的深度与栈帧大小的关系:
private int count = 0;

public void depthOfStack() {
    try {
        count ++;
        depthOfStack();
    } catch (Throwable e) {
        System.out.println("depthOfStack = " + count);
    }
}

public static void main(String[] args) throws IOException {
    new TpmaApplication().depthOfStack();
}

测试多次之后结果并不是完全相同,至于为什么不同,笔者并不清楚:

depthOfStack = 12234
depthOfStack = 12167
depthOfStack = 11923
depthOfStack = 11989
public void depthOfStack(int a, int b, int c) {
    try {
        count ++;
        depthOfStack(a, b, c);
    } catch (Throwable e) {
        System.out.println("depthOfStack = " + count);
    }
}

public static void main(String[] args) throws IOException {
    new TpmaApplication().depthOfStack(1, 2 , 3);
}

测试多次之后:

depthOfStack = 9839
depthOfStack = 9809
depthOfStack = 9719
depthOfStack = 10011

由此可见,栈深度整体小了不少。

发布了48 篇原创文章 · 获赞 2 · 访问量 6328

猜你喜欢

转载自blog.csdn.net/qq_39291919/article/details/103730283