Java虛擬機(一)—— 虛擬機原理


先來看下面這一段代碼:

public class APP {
    public int add() {
        int a = 1;
        int b = 2;
        int c = (a+b)*3;
        return c;
    }

    public static void main(String[] args) {
        APP app1 = new APP();
        System.out.println(app1.add());
        APP app2 = new APP();
        System.out.println(app2.add());
    }
}

代碼的大體執行過程

JDK、JRE、JVM的區別和聯繫

代碼的大體執行過程如下:
在這裏插入圖片描述
從.java源文件編譯生成.class字節碼文件的過程如下:
在這裏插入圖片描述

代碼在JVM裏面的詳細執行過程

在JVM內部就這個樣子的:
在這裏插入圖片描述

類裝載子系統

然後,先說說類裝載子系統
在這裏插入圖片描述

類加載器詳解

class文件的加載過程詳細的可以看我的另一篇博客,類加載器

運行時數據區

然後是運行時數據區(內存模型)的:
在這裏插入圖片描述

運行時數據區詳解

從上面的運行時數據區(內存模型)的模型圖我們可以看到,堆和方法區是線程之間共享的(會發生併發安全的地方),而虛擬機棧、本地方法棧、程序計數器是線程私有的(也就是每個線程都已自己的虛擬機棧、本地方法棧和程序計數器),下面是關於內存模型中各個部分的介紹:

  • 程序計數器(線程私有):就是一個指針,指向方法區中的方法字節碼(用來存儲下一條指令的地址,也就是馬上要執行的指令的地址),有執行引擎讀取下一條指令,是一個非常小的空間,幾乎可以忽略不計;
  • 方法區(線程共享):類的所有字段和方法字節碼,以及一些特殊方法如:構造函數,接口代碼也在此定義,簡單說,所有定義的方法的信息都保存在該區域,靜態變量+常量+類信息(構造方法/接口定義)+運行時常量池都存在方法區中
  • 虛擬機棧(線程私有):Java線程執行方法的內存模型,一個線程對應一個棧,每個方法在執行的同時都會創建一個棧幀(用於存儲局部變量表,操作數棧,動態鏈接,方法出口等信息),不存在垃圾回收等問題,只要線程一結束就釋放,生命週期和線程一致;
  • 本地方法棧(線程私有):就是存放哪些native方法的;
  • 堆(線程共享):很大的一塊空間,用於存放對象實例,垃圾回收主要發生的地方;

棧幀中的組成部分介紹:

  • 局部變量表:可以這麼理解,局部變量表裏面存放的是一個一個的小容器,用來存放數據的,比如我們開頭那段代碼中的a = 1, b = 2,在虛擬機裏面不可能真給你弄出一個a、b來存放1和2,於是就用局部變量表中的這些小容器來存放,比如容器1存放1,容器2存放2,容器3存放他們的計算結果300……,當然,除了能存放基本的數據類型以外,還可以存放引用類型的對象指針;
  • 操作數棧:每次要進行操作時(相加、相減、乘除等等),先把相關的數都放到操作數棧裏面,讓後繼續相關的操作,並將操作的結果放到局部變量表中去;
  • 動態鏈接:比如上面那個main方法運行到第二行就要進入到add()方法中去了,就是在運行的時候將符號引用轉化爲直接引用;
  • 方法出口:比如上面的代碼,add()方法運行完之後,還要將結果返回給main方法的,這個主要指的是return一類的;

在這裏插入圖片描述

執行引擎

最後是執行引擎:
在這裏插入圖片描述

至於堆的組成部分和垃圾回收在下一篇垃圾回收中在介紹吧!

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