JVM位元組碼執行引擎和動態繫結原理

2022-04-01 01:17:56 字數 1001 閱讀 1850

編譯期就確定了需要多大的區域性變數表,多深的運算元棧,這些資訊全在位元組碼中。

只有位於棧頂的棧幀才有效,稱為當前棧幀,所對應的方法就是當前正在執行的方法。

容量以變數槽slot為單位,slot記憶體大小隨著需求而變化並且不固定。

方法執行時jvm使用區域性變數表完成引數值到引數列表的傳遞過程。

slot可以被其他變數復用。

區域性變數不存在準備階段,所以不會賦予系統初始值,如果不初始化那麼他就不能使用。

jvm通過索引定位的方式定位slot,從0到最大slot數量。0位索引slot是用來存放方法所屬物件例項的引用(this),之後按引數列表分配slot,再後按照區域性變數順序分配slot。

類載入的解析階段會把 部分符號引用轉化為直接引用,但這種解析的前提條件就是:方法在程式執行之前就有乙個就可以確定的版本,並且在執行期間不可變。

編譯期可知執行期不可變這種方法有static和private方法,想想也是,這兩種方法只有定義他們的類才能呼叫,他們一出生就確定了唯一的主人。他們不可能被繼承或者重寫其他版本。

例項構造器,父類方法這2中也能確定唯一的版本,所以這些方法也是在類載入階段解析為直接引用。

靜態方法,私有方法,例項構造器,父類方法這些方法可確定唯一版本所以統稱為 非虛方法,final方法也是非虛方法。

靜態型別和動態型別

靜態分派:根據引數的靜態型別確定該方法使用的版本

動態分派:執行期間根據呼叫方法的物件的實際型別確定使用哪個類的方法,也就是確定使用哪個重寫方法。編譯期間無法確定實際型別找到呼叫當前方法的物件的實際型別

在實際型別中由靜態分派確定方法版本。

如果找到對應版本則檢查訪問許可權如果通過則返回此方法的引用。

如果找不到則從下往上在父類中找,如果找不到則丟擲異常。

單分派多分派

靜態分派和動態分派的區別靜態分派通過引數型別查詢過載版本,並且是引數的靜態型別。

動態分派通過呼叫方法的物件查詢重寫版本,並且是物件的實際型別。

當乙個引用變數它的編譯時的型別和執行是的型別不一樣時:

jvm 位元組碼執行流程

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

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

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

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

我的 github 部落格 編譯的結果從本地機器碼轉變為位元組碼,是儲存格式發展的一小步,卻是程式語言發展的一大步 首先,丟擲靈魂三問 如果你對上述問題理解得還不是特別透徹的話,可以看下這篇文章 如果理解了,你可以關閉網頁,開啟遊戲放鬆了hhh 下面,筆者將帶你 jvm核心的組成部分之一 執行引擎。...