一夜搞懂 JVM 位元組碼執行引擎

2022-05-22 13:09:06 字數 2842 閱讀 8076

我的 github 部落格

**編譯的結果從本地機器碼轉變為位元組碼,是儲存格式發展的一小步,卻是程式語言發展的一大步

首先,丟擲靈魂三問:

如果你對上述問題理解得還不是特別透徹的話,可以看下這篇文章;如果理解了,你可以關閉網頁,開啟遊戲放鬆了hhh

下面,筆者將帶你**jvm核心的組成部分之一——執行引擎。

q1:虛擬機器與物理機的異同

q2:有關jvm位元組碼執行引擎的概念模型

2.2.1 基本概念
筆者之前在 一文洞悉 jvm 記憶體管理機制 中就談到過虛擬機器棧,相信看過的讀者都有印象

2.2.2 區域性變數表

2.2.3 運算元棧

2.2.4 動態連線

class檔案的常量池中存有大量的符號引用,位元組碼中的方法呼叫指令就以常量池中指向方法的符號引用作為引數,這些符號引用:

2.2.5 方法返回位址

下面筆者將為大家詳細講解方法呼叫的型別

2.3.1 解析呼叫
筆者之前在 一夜搞懂 | jvm 類載入機制中就談到過解析,感覺有點混淆的,可以回去看下

2.3.2 分派呼叫

q1:什麼是靜態型別?什麼是實際型別?

a1:這個用**來說比較簡便, talk is cheap ! show me the code !

//父類

public class human

//子類

public class man extends human

public class main 

}

1.靜態分派
單純說未免有些許抽象,所以特地用下面的demo來幫助了解

public class father 

public class son extends father

public class daughter extends father

public class hello 

public void sayhello(daughter daughter)

public void sayhello(son son)

}

public static void main(string args)
輸出結果如下:

hello , i am the father

hello , i am the father

我們的編譯器在生成位元組碼指令的時候會根據變數的靜態型別選擇呼叫合適的方法。就我們上述的例子而言:

2.動態分派

public class father 

}//繼承 + 方法重寫

public class son extends father

}

public static void main(string args)
輸出結果如下:

hello world ---- son

我們接著來看一下位元組碼指令呼叫情況

疑惑來了,我們可以看到,jvm選擇呼叫的是靜態型別的對應方法,但是為什麼最終的結果卻呼叫了是實際型別的對應方法呢?

當我們將要呼叫某個型別例項的具體方法時,會首先將當前例項壓入運算元棧,然後我們的invokevirtual指令需要完成以下幾個步驟才能實現對乙個方法的呼叫:

因此,疑惑自然解決了

3.單分派

4.多分派

恭喜你!已經看完了前面的文章,相信你對jvm位元組碼執行引擎已經有一定深度的了解!你可以稍微放鬆獎勵自己一下,可以睡乙個美美的覺,明天起來繼續衝衝衝!!!

如果文章對您有一點幫助的話,希望您能點一下贊,您的點讚,是我前進的動

一夜搞懂 JVM 執行緒安全與鎖優化

我的 github 部落格 之前我們學習了記憶體模型和執行緒,了解了jmm和執行緒,初步 了jvm怎麼實現併發,而本篇文章,我們的關注點是jvm如何實現高效 併發程式設計的目的是為了讓程式執行得更快,提高程式的響應速度,雖然我們希望通過多執行緒執行任務讓程式執行得更快,但是同時也會面臨非常多的挑戰,...

jvm 位元組碼執行流程

1 源 public class mytest 2 編譯後的位元組碼檔案 3 載入 1 常量池中的位元組碼載入到執行時常量池 2 方法的位元組碼載入到方法區 4 main執行緒開始執行,分配棧楨記憶體 1 棧記憶體的分配 區域性變數表 4 最大運算元棧的深度為 2 2 執行istore 1指令 將常...

JVM之虛擬機器位元組碼執行引擎

執行時棧幀結構 棧幀儲存方法的區域性變數表 運算元棧 動態鏈結和方法返回位址等,每乙個方法由開始到結束,都對應著乙個棧幀在虛擬機器裡面的出棧入棧過程。對於執行引擎來說,在活動的執行緒中,只有位於棧頂的棧幀才有效,叫做當前棧幀,與這個棧幀相關聯的方法叫做當前方法。區域性變數表 是一組變數值儲存空間,存...