通過一個簡單的例子來看看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
在這裏插入圖片描述
將操作數棧中的值.作爲方法返回值返回

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