通过一个简单的例子来看看jvm来理解局部变量表和操作数栈

JVM内存模型
JVM内存模型如上图所示.但是运行时方法在java代码运行时是如何运转的呢.下面我们通过一个简单的代码来看看运行时方法区的各个模块是如何运转的

package com.bonc.jvm;

/**
 * @Classname JVMTest
 * @Description TODO
 * @Date 2020/6/14 10:54
 * @Created by sz
 */
public class JVMTest {

    public static User user = new User();
    private final  static  int  initData=1111;

    public int computer(){
        int a =1;
        int b= 2;
        int c=(a+b)*15;

        return c;
    }

    public static void main(String[] args) {
        JVMTest jvmTest =new JVMTest();
        int computer = jvmTest.computer();
        System.out.println(computer);
    }
}

通过java自带的javap -c命令可以查看编译完,我们稍微可以理解的代码

Compiled from "JVMTest.java"
public class com.bonc.jvm.JVMTest {
  public static com.bonc.jvm.User user;

  public com.bonc.jvm.JVMTest();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public int computer();
    Code:
       0: iconst_1
       1: istore_1
       2: iconst_2
       3: istore_2
       4: iload_1
       5: iload_2
       6: iadd
       7: bipush        15
       9: imul
      10: istore_3
      11: iload_3
      12: ireturn

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class com/bonc/jvm/JVMTest
       3: dup
       4: invokespecial #3                  // Method "<init>":()V
       7: astore_1
       8: aload_1
       9: invokevirtual #4                  // Method computer:()I
      12: istore_2
      13: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
      16: iload_2
      17: invokevirtual #6                  // Method java/io/PrintStream.println:(I)V
      20: return

  static {};
    Code:
       0: new           #7                  // class com/bonc/jvm/User
       3: dup
       4: invokespecial #8                  // Method com/bonc/jvm/User."<init>":()V
       7: putstatic     #9                  // Field user:Lcom/bonc/jvm/User;
      10: return
}

java 虚拟机运行一个线程会给当前线程分配一个栈空间.栈空间是有许多栈帧组成.每执行一个方法会给单前方法分配一个栈帧空间.栈帧空间有局部变量表,操作数栈,动态链接,方法出口.操作数栈:是指方法执行时临时存放操作数的内存空间.
栈内方法
我们先看一下方法computer的反汇编代码
computer反汇编代码
执行完第一个反汇编代码.查看操作手册代码 JVM指令手册下载地址:传送门
在这里插入图片描述
执行完computer内存空间为
在这里插入图片描述
执行完istore_1 查看手册这里的局部变量1值得是局部变量表中第一个这里的局部变量1值得是局部变量表中第一个局部变量.也就是a
所以执行完这几行代码的结果为
执行完第二行代码后的结果
下面的 2: iconst_2 3: istore_2 这两行代码执行完之后内存空间的
在这里插入图片描述
下面执行iload_1查指令手册
在这里插入图片描述
将局部变量表局部变量1放入操作数栈中
在这里插入图片描述
同理执行iload_2 将局部变量表局部变量2放入操作数栈中
所以至此jvm内存空间中的东西变成
在这里插入图片描述
执行6: iadd 查指令手册 执行int类型的加法
将操作数栈中的变量拿到cpu中做加法算法,将执行结果重新压回操作数栈中
所以执行结果为
在这里插入图片描述
执行下一步bipush 15 查指令手册
在这里插入图片描述
也就是将15压入操作数栈中
在这里插入图片描述
接下来执行imul 查指令手册在这里插入图片描述
也就是将操作数栈中的数字拿到cpu中执行乘法,执行结果返回到操作数栈中
在这里插入图片描述
下面一步执行istore_3在这里插入图片描述 和前面将操作数栈中的值45存入局部变量3中

在这里插入图片描述
再接着执行iload_3 查指令手册
在这里插入图片描述
讲局部变量表中局部变量3的数值加载到操作数栈中
在这里插入图片描述
再执行ireturn
在这里插入图片描述
将操作数栈中的值.作为方法返回值返回

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章