1. 程式人生 > >JVM(11)——執行時棧幀結構

JVM(11)——執行時棧幀結構

1. 概述

“虛擬機器”是一個相對於“物理機”的概念,這兩種機器都有程式碼執行能力,其區別是物理機的執行引擎是直接建立在處理器、硬體、指令集和作業系統層面上的,而虛擬機器的執行引擎則是由自己實現的,因此可以自行制定指令集與執行引擎的結構體系,並且能夠執行那些不被硬體直接支援的指令集格式。

在不同的虛擬機器實現裡面,執行引擎在執行Java程式碼的時候可能有解釋執行和編譯執行兩種選擇,也可能兩者兼備,甚至還可能包含幾個不同級別的編譯器執行引擎。

這裡寫圖片描述

2. 執行時棧幀結構

棧幀是用於支援虛擬機器進行方法呼叫和方法執行的資料結構,它是虛擬機器執行時資料區中的虛擬機器棧的棧元素。棧幀儲存了方法的區域性變量表、運算元棧、動態連線和方法返回地址等資訊。每一個方法從呼叫開始到執行完成的過程,就對應著一個棧幀在虛擬機器棧裡面從入棧道出棧的過程。

在編譯程式程式碼的時候,棧幀中需要多大的區域性變量表、多深的運算元棧都已經完全確定了,並且寫入到方法的code屬性之中,因此一個棧幀需要分配多少記憶體,不會受到程式執行期變數資料的影響,而僅僅取決於具體的虛擬機器實現。

(1)區域性變量表

區域性變量表是一組變數值儲存空間,用於存放方法引數方法內部定義的區域性變數。在Java程式被編譯為Class檔案時,就在方法的Code屬性的max_locals資料項中確定了該方法所需要分配的最大區域性變量表的容量。

區域性變量表的變數以變數槽(Slot)為最小單位,虛擬機器規範中並沒有明確指明一個Slot應占用的記憶體空間大小。

虛擬機器通過索引定位的方式使用區域性變量表,索引值的範圍是從0開始到區域性變量表最大的Slot數量。在方法執行時,虛擬機器是使用區域性變量表完成引數值到引數變數列表的傳遞過程的,如果是例項方法(非static方法),那麼區域性變量表中第0位索引的Slot預設是用於傳遞方法所屬物件例項的引用,在方法中可以通過關鍵字“this”來訪問這個隱含的引數。其餘引數則按照引數表的順序來排列,佔用從1開始的區域性變數Slot,引數表分配完畢後,再根據方法體內部定義的變數順序和作用域分配其餘的Slot。

區域性變量表中的Slot是可重用的,方法體中定義的變數,其作用於並不一定會覆蓋整個方法體,如果當前位元組碼PC計數器的值已經超出了某個變數的作用域,那麼這個變數對應的Slot就可以交給其他變數使用。

對於64位的資料型別,虛擬機器會以高位在前的方式為其分配兩個連續的Slot空間。

(2)運算元棧

運算元棧也常被稱為操作棧,它是一個後入先出棧。同區域性變量表一樣,運算元棧的最大深度也是在編譯的時候被寫入到Code屬性的max_stacks資料項中。32位資料型別所佔的棧容量位1,64位資料型別所佔的棧容量位2.

當一個方法剛剛開始執行的時候,這個方法的運算元棧是空的,在方法的執行過程中,會有各種位元組碼指令向運算元棧中寫入和提取內容,也就是入棧出棧操作。舉個例子:整數加法位元組碼指令iadd

在執行的時候要求運算元棧中最接近棧頂的兩個元素已經存入了兩個int型別的數值,當執行這個指令時,會將這兩個int值出棧並相加,然後將相加的結果入棧。

運算元棧中元素的資料型別必須與位元組碼指令的序列嚴格匹配,在編譯程式程式碼的時候,編譯器要嚴格保證這一點,在類校驗階段的資料流分析中還要再次驗證這一點。

(3)動態連線

每個棧幀都包含一個指向執行時常量池中該棧幀所屬方法的引用,持有這個引用是為了支援方法呼叫過程中的動態連線。

(4)方法返回地址

當一個方法被執行後,有兩種方式退出這個方法。第一種方式是:執行引擎遇到任意一個方法返回的位元組碼指令,這時候可能會有返回值傳遞給上層的方法呼叫者(呼叫當前方法的方法稱為呼叫者),是否有返回值和返回值型別將根據遇到各種方法返回指令來決定,這種退出方法的方式稱為正常完成出口

另一種退出方式是,在方法執行過程中遇到了異常,並且這個異常沒有在方法體內得到處理,無論是Java虛擬機器內部產生的異常,還是程式碼中使用athrow位元組碼指令產生的異常,只要在本方法的異常表中沒有搜尋到匹配的異常處理器。就會導致方法退出,這種退出方法的方式稱為異常完成出口

無論採用何種退出方式,在方法退出後,都需要返回到方法被呼叫的位置,程式才能繼續執行,方法返回時可能需要在棧幀中儲存一些資訊,用來幫助恢復它的上層方法的執行狀態。一般來說,方法正常退出時,呼叫者的PC計數器的值就可以作為返回地址,棧幀中很可能會儲存這個計數器值。而方法異常退出時,返回地址是要通過異常處理器表來確定,棧幀中一般不會儲存這部分資訊。

方法退出的過程實際上等同於把當前棧幀出棧,因此退出時可能執行的操作有:回覆上層方法的區域性變量表和運算元棧,把返回值(如果有的話)壓入呼叫者棧幀的運算元棧中,調整PC計數器的值以指向方法呼叫指令後面的一條指令等。

相關推薦

JVM11——執行結構

1. 概述 “虛擬機器”是一個相對於“物理機”的概念,這兩種機器都有程式碼執行能力,其區別是物理機的執行引擎是直接建立在處理器、硬體、指令集和作業系統層面上的,而虛擬機器的執行引擎則是由自己實現的,因此可以自行制定指令集與執行引擎的結構體系,並且能夠執行那些不

【學習筆記】深入理解js原型和閉包11——執行上下文

繼續上文的內容。 執行全域性程式碼時,會產生一個執行上下文環境,每次呼叫函式都又會產生執行上下文環境。當函式呼叫完成時,這個上下文環境以及其中的資料都會被消除,再重新回到全域性上下文環境。處於活動狀態的執行上下文環境只有一個。 其實這是一個壓棧出棧的過程——執行上下文棧。如下圖:   可

深入理解JVM——執行的資料區域

Java與C++的圍牆:記憶體動態分配,垃圾收集技術 程式計數器 當前執行緒所執行的位元組碼的行號指示器,通過改變這個計數器的值來選擇下一條執行的位元組碼指令,分支,迴圈,跳轉,異常處理,執行緒恢復等依賴計數器。 執行緒私有,唯一不會OutOfMemory的區域。 執行Jav

虛擬機器位元組碼執行引擎——執行結構

文章目錄 一、區域性變量表 二、運算元棧 三、動態連線 四、方法返回地址 五、附加資訊 虛擬機器與物理機異同 同:都具有程式碼執行能力 異:物理機的執行引擎是建立在處理器、硬體、指令集和作業系

深入理解Java虛擬機器之類執行結構

棧幀(Stack Frame)是用於支援虛擬機器進行方法呼叫和方法執行的資料結構,它是虛擬機器執行時資料區中的虛擬機器棧(Virtual Machine Stack)的棧元素。棧幀儲存了方法的區域性變量表、運算元棧、動態連線和方法返回地址等資訊。每一個方法從呼叫

JAVA記憶體結構執行結構

http://www.360doc.com/content/14/0925/13/1073512_412236522.shtml 感謝原創者的付出 ---------------------------------------------------------------

Java編譯原理--執行結構

Java語言在剛剛誕生的時候提出過一句著名的口號“一次編寫,到處執行”,這句話充分的表達了開發人員對於衝破平臺界限的渴望,也解釋了Java語言跟平臺無關的設定。  一、 概述 Java虛擬機器規定了虛擬機器執行位元組碼的概念模型,這個模型是各類虛擬機器的外觀結構,不同的虛

執行結構

棧幀是用於支援虛擬機器進行方法呼叫和方法執行的資料結構 棧幀儲存了方法的區域性變量表,運算元棧,動態連線,方法返回地址等資訊,每一個方法從呼叫開始直至執行完成的過程都對應著一個棧幀從入棧到出棧的過程 區域性變數: 是一組變數值儲存空間,用於儲存方法引數和方法內部定義的區域性變數 最小

14 執行結構

《深入理解Java虛擬機器:JVM高階特性與最佳實踐(第2版)》8.2節 不同的虛擬機器實現在執行Java程式碼時可能會有解釋執行(通過直譯器執行)和編譯執行(通過即時編譯器產生原生代碼執行)兩種選擇 棧幀(Stack Frame) 用於支援虛擬機器進行方法呼叫和方法執

JVM理論:三/3運行結構、基於的字節碼解釋執行過程

指向 stat 中一 指令執行過程 字節碼指令 輸出 作用 引擎 jvm 一、棧幀結構   講棧幀結構有必要回顧一下前文Class文件中的Code屬性結構,如下圖。      棧幀是用於支持虛擬機進行方法調用和方法執行的數據結構,它是虛擬機棧的棧元素。每一個方法從調用開始到

JVM學習筆記執行資料區

執行時資料區     java虛擬機器在執行java程式的過程中會把所管理的記憶體劃分為若干個不同的資料區域。這些區域都有各自的用途,以及建立和銷燬的時間。 有的區域隨著虛擬機器程序的啟動而存在,隨虛擬機器程序的退出而銷燬; 有的區域則依賴使用者執行緒的啟

JavaScript執行環境及作用域——執行環境和作用域鏈機制

執行環境是JavaScript中最為重要的一個概念,每個執行環境都有一個與之關聯的變數物件,執行環境中所有的變數和函式都儲存在這個物件中。我們編寫的程式碼是無法訪問這個變數物件的,只有解析器在處理資料時會在後臺使用它,但有個例外,因為在Web瀏覽器中,全域性執行環境關聯的變數物件是window物件,windo

C#學習筆記11- 執行緒類與程序類

為什麼要使用多執行緒? 讓計算機“同時”做多件事情,節約時間 多執行緒可以讓一個程式“同時”處理多個事情 後臺執行程式,提高程式的執行效率,也不會使主介面出現無響應的情況 獲得當前執行緒與當前程序 前臺執行緒與後臺執行緒 前臺執行緒:只有所

JVM----------------執行緒安全之鎖機制

鎖機制是JAVA虛擬機器實現執行緒安全的方法之一。在這裡介紹幾個鎖優化 鎖優化技術(HotSpot虛擬機器而言)包括適應性自旋、鎖消除、鎖粗化、輕量級鎖和偏向鎖等。這些技術都是為了線上程之間更高效地共享資料以及解決競爭問題,從而提高程式效率。 1.自旋鎖與自適應自旋

機房收費系統登陸客戶端錯誤執行錯誤“-2147217887”

解決了執行錯誤91之後可能還會出現這個錯誤,如圖: 什麼是OLE DB?OLEDB是微軟的戰略性的通向不同的資料來源的低階應用程式介面。OLE DB不僅包括微軟資助的標準資料介面開放資料庫連通性(ODBC)的結構化查詢語言(SQL)能力,還具有面向其他非SQL

java記憶體管理機制-執行資料區

前言   本打算花一篇文章來聊聊JVM記憶體管理機制,結果發現越扯越多,於是分了三遍文章(文章講解JVM以Hotspot虛擬機器為例,jdk版本為1.8),本文為其中第一篇。from java記憶體管理機制(一)-執行時資料區    1、 java記憶體管理機制-執行時資料區

iOS程式設計基礎-OC-執行系統

第7章 執行時系統  7.4 動態繫結      動態繫結(dynamic binding):         是指在執行程式時(而不是在編譯時)將訊息與方法對應起來的處理過程;

ARMv8架構下程式執行佈局

結合ARM相關文件和在飛騰機器上使用gdb除錯實際程式來研究ARM的指令和執行時棧幀佈局。主要參考了三篇文件。 1. Procedure Call Standard for the ARM 64-bit Architecture。參考其中的過程呼叫標準和執行時棧幀佈局。 2

iOS程式設計基礎-OC-執行系統

 第7章 執行時系統      終於到了執行時這一章,讓我們來一步一步揭開它神祕的面紗吧;      OC擁有相當多的動態特性,這些特性在執行程式時發揮作用,而不是在編譯或連結程式碼時發

Java虛擬機器詳解------執行記憶體結構

  首先通過一張圖瞭解 Java程式的執行流程:      我們編寫好的Java原始碼程式,通過Java編譯器javac編譯成Java虛擬機器識別的class檔案(位元組碼檔案),然後由 JVM 中的類載入器載入編譯生成的位元組碼檔案,載入完畢之後再由 JVM 執行引擎去執行。在載入完畢到執行過程中,J