1. 程式人生 > >虛擬機器---3.執行

虛擬機器---3.執行

接著上一篇的載入,存成虛擬機器要求的結構。那下一步就是程式碼的執行。

位元組碼已經載入進來,肯定是你new了它,或者其他情況觸發了它的載入。

打比如new了它,也就載入、連結(驗證、準備、解析)、初始化了。再接著就是例項化。例項化,這個過程是啥,就是執行。這過程涉及到啥?怎麼樣把位元組碼轉化成機器碼(裝置可識別程式碼)?

虛擬機器抽象定義,new這個操作就是一個棧幀,平時列印異常,記得不,e.printstack(異常列印的就是每個棧幀)。那其實就是一個一個的單元。按方法設計。理解每個方法,那就是理解全部。

方法裡面又是怎麼玩?二進位制檔案(位元組碼)那會,又棧的深度,區域性變數個數,linetablename(原始碼和位元組碼的對應關係),基本就說出來了。區域性變量表(最小單位slot槽),方法棧(存的也是即將要用的數值),程式計數器(程式碼執行到第幾行,偏移地址),還有返回地址(執行完這個方法回到哪裡去,肯定是別人呼叫了這方法才執行啊);

 

 

由上面圖片,看到main方法,顯示

先建立一個物件,並將其引用值(對應堆裡面的首地址)存到棧頂,

取棧頂值,並把它返回給棧頂

invokespecial虛擬機器裡方法呼叫指令,這個是呼叫建構函式,編譯器就儲存了指定的類與方法描述符

以上就new XiaoQiang()

把常量推送至棧頂

虛擬函式呼叫,這裡是靜態繫結,編譯器就識別setName("XXXXXx")

返回

 

上面講了這麼多。就是方法與方法直接的呼叫,助記符的執行,還有很多概念沒涉及到。

比如

1、區域性變量表,這裡除了this,沒有其他區域性變量表,故local:1;其他比如助記符isotre_1就是把棧頂常量存入區域性變量表。

2、方法呼叫指令invokespecial(構造),invokeinterface(介面),invokeviture(重寫過載,常規的也是),invokestatic(靜態)

新增invokedynamic,呼叫了methodhandler,方法的歸屬交給程式碼編寫者決定。

3、方法繫結,編譯期確定,執行期確定,程式碼敲寫確定

編譯器確定通過類符號和方法符號,及描述符號確定

執行期確定,通過優化手段方法表,也就是每個方法的索引;

 

以上的每一行助記符都是我自己大腦識別,機器呢?

虛擬機器有兩種辦法,解釋執行和編譯執行;解釋把位元組碼一行一行的code解釋成機器碼;編譯執行,把位元組碼統統一次性編譯成機器碼。虛擬機器採用了結合兩種方式的優劣,一起幹。經常性執行程式碼,直接編譯成機器碼。不經常用的,解釋執行。解釋執行,可以結合執行時資訊,靈活優化。怎麼區分經常性執行與非經常性識別呢?專業術語,熱點程式碼,常用計數方式識別。

編譯器好幾個。不同編譯器優劣不同。有注重啟動快速,執行消峰等。