JVM底層原理分析

JVM的內存模型很多人都看過,周志明老師的《深入理解Java虛擬機》已經解釋的很清楚了。但是只限於概念性的知識,關於底層的原理並沒有做深入的闡述,下面我們通過一個實例代碼來分析JVM內存模型之間的聯繫與各模塊之間的底層原理,底層比較複雜,可能篇幅有點長,請耐心閱讀,一定給你講透徹,閱讀本文建議同《深入理解JVM》這本書一起參考。

此處先上一段代碼,以下通過代碼逐步分析:


public class Math {
	public int compute(){          //一個方法對應一塊棧幀內存區域
		int a=1;
		int b=2;
		int c=(a+b)*10;
		return c;
	}
	public static void main(String[] args) {
		Math math=new Math();
		math.compute();
	}
}

這段代碼生成的字節碼文件如下:


Compiled from "Math.java"
public class com.lucas.Demo1.Math {
  public static final java.lang.Integer CONATANT;

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

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

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class com/lucas/Demo1/Math
       3: dup
       4: invokespecial #3                  // Method "<init>":()V
       7: astore_1
       8: aload_1
       9: invokevirtual #4                  // Method compute:()I
      12: pop
      13: return

  static {};
    Code:
       0: sipush        666
       3: invokestatic  #5                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       6: putstatic     #6                  // Field CONATANT:Ljava/lang/Integer;
       9: return
}

還是先上最經典的那一幅JVM內存模型圖:
在這裏插入圖片描述

我們先來分析虛擬機棧的內存結構(圖中箭頭可以不考慮,只是局部的圖):
在這裏插入圖片描述

以上圖片的名詞在此不做解釋,默認讀者已經知道,我們主要探究每一塊區域的底層原理。

以上java在執行時,線程main在虛擬機棧內存中開闢一塊空間。每個方法按照順序依次進棧,每一個方法在執行時開闢一個棧幀,棧幀中存儲的信息見上圖。下面依次解釋每一個區域的作用:以下不講定義,只是以上面代碼爲實例,加上作者本人的理解,如有偏差,請自行取捨。

局部變量表:

故名思意就是存放局部變量的,以上代碼中,在 compute() 方法創建的棧幀的局部變量表中存放的是:a,b,c三個局部變量,在 main() 方法創建的棧幀的局部變量表中存放的是 math這個變量。

操作數棧:

在作者的理解看來,操作數棧就是一箇中轉站。
對照前面的字節碼指令,我們可以很清晰的知道了每一步,虛擬機的底層幹了哪些事。
第一步,執行iconst命令
將一個常量加載到操作數棧在這裏插入圖片描述
這時我們可以看到操作數棧中有2個常量 1 和 2;

第二步:執行字節碼指令istore,將整型類型值存入局部變量中,並將操作數棧的內存釋放出來。
在這裏插入圖片描述
第三步:執行字節碼指令:

    4: iload_1
    5: iload_2
    6: iadd
    7: bipush        10
    9: imul
    10: istore_3
    11: iload_3
    12: ireturn

:從局部變量中裝載第一個int類型的值到操作數棧
在這裏插入圖片描述
以上圖片難以準確的解釋程序執行時JVM的執行流程,建議研究以上字節碼文件,指令可查看字節碼指令手冊,其實研究JVM的工作流程,最好的方式就是研究字節碼文件。

動態連接區域:

筆者尚未徹底明白。。。歡迎朋友們給我留言,交流

筆者理解的JVM圖:
在這裏插入圖片描述

關於GC:

GC算法請參考我的另一篇文章:
https://blog.csdn.net/weixin_42146996/article/details/102571871

還是先上圖:
在這裏插入圖片描述

上圖我覺得已經解釋的很詳細了,筆者很懶,不想再多解釋了

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