JVM——Java栈

每当启动一个新线程时,Java虚拟机都会为它分配一个Java栈。Java栈以帧为单位保存线程的运行状态。虚拟机只会直接对Java栈执行两个操作:以帧为单位的压栈或出栈。当线程调用一个Java方法时,虚拟机都会在该线程的Java栈中压入一个新栈。

栈帧:

栈帧由三部分组成:局部变量,操作数栈和栈数据区。

当虚拟机调用一个Java方法时,它从对应类的信息中得到此方法的局部变量和操作数据栈的大小,并据此分配栈帧内存,然后压入Java栈中。

1)局部变量:Java栈帧的局部变量区被组织为一个以字节为单位,从0开始计数的数组。

2)操作数栈:和局部变量一样,被组织成一个字长为单位的数组。通过标准的栈操作——压栈和出栈来访问。

3)栈数据区:Java栈中支持常量池解析,正常方法返回以及异常派发机制的一些信息。

例子:

一个斐波那契序列的代码,如下:

class Fibonacci {

    static void calcSequence() {
        long fiboNum = 1;
        long a = 1;
        long b = 1;

        for (;;) {
            fiboNum = a + b;
            a = b;
            b = fiboNum;
        }
    }
}
指令码:

 0 lconst_1   // Push long constant 1
 1 lstore_0   // Pop long into local vars 0 & 1: long a = 1;
 2 lconst_1   // Push long constant 1
 3 lstore_2   // Pop long into local vars 2 & 3: long b = 1;
 4 lconst_1   // Push long constant 1
 5 lstore 4   // Pop long into local vars 4 & 5: long fiboNum = 1;
 7 lload_0    // Push long from local vars 0 & 1
 8 lload_2    // Push long from local vars 2 & 3
 9 ladd       // Pop two longs, add them, push result
10 lstore 4   // Pop long into local vars 4 & 5: fiboNum = a + b;
12 lload_2    // Push long from local vars 2 & 3
13 lstore_0   // Pop long into local vars 0 & 1: a = b;
14 lload 4    // Push long from local vars 4 & 5
16 lstore_2   // Pop long into local vars 2 & 3: b = fiboNum;
17 goto 7     // Jump back to offset 7: for (;;) {}

虚拟机镜像:

1)初始化。Local Variables:局部变量。Operand Stack:操作数栈。


2)分配3个变量:fiboNum,a,b。局部变量是一个3位的数组。


3)lload_0:从局部变量0中装载long类型值,lload_2:从局部变量2中装载long类型值。


4)ladd:执行int类型的加法。


5)istore 4:从栈中弹出int类型值,然后将其存到位置为4的局部变量中。





参考资料:

《深入Java虚拟机》


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值