淺談 JVM 1:一次編寫,到處運(yùn)行

不同于 C、C++ 無(wú)需運(yùn)行時(shí)可直接編譯為機(jī)器碼運(yùn)行,Java 程序需要運(yùn)行在 JRE 之上。而正因如此,Java 擁有了 C、C++ 所不具有的可移植性。而在 JRE 之中,JVM 又是一個(gè)重要的組成。
之所以要大費(fèi)周章地編寫 Linux、macOS、Windows 平臺(tái)的 JVM,其中之一便是因?yàn)?Java “一次編寫,到處運(yùn)行” 的設(shè)計(jì)理念。
打開(kāi)?Java 官網(wǎng)[1]?可以看到以下內(nèi)容:

Java SE 的每個(gè)版本都包含兩部分:
?Java 語(yǔ)言規(guī)范;?虛擬機(jī)規(guī)范。
我們?cè)俳Y(jié)合 Java、JRuby 等語(yǔ)言的編譯執(zhí)行過(guò)程來(lái)看,如下圖:

可以看到?Java 官方之所以要將 Java 語(yǔ)言規(guī)范和虛擬機(jī)規(guī)范分別定義,就是為了讓多種語(yǔ)言如 Java、JRuby、Jython、Groovy 等都可以運(yùn)行在 JVM 之上。Java 并不是 JVM 支持運(yùn)行的唯一語(yǔ)言。
2018 年推出的 GraalVM,更是有一統(tǒng)天下語(yǔ)言運(yùn)行時(shí)之趨勢(shì)??梢詤⒁?jiàn)?GraalVM 官網(wǎng)[2]。
這其中的關(guān)鍵之一就是 class 文件。任何操作系統(tǒng)上編寫的 Java 等語(yǔ)言的代碼都可以編譯為 class 字節(jié)碼,然后將其交給不同平臺(tái)的 JVM 解析、加載、鏈接、編譯、執(zhí)行。
JVM 除了能夠執(zhí)行 class 文件,讓語(yǔ)言能夠一次編寫多處運(yùn)行之外。還有以下特性支持:
?內(nèi)存管理?垃圾回收?數(shù)組越界等安全保護(hù)機(jī)制
既然 JVM 執(zhí)行的是 class 字節(jié)碼,而非原生 Java 代碼。同時(shí)又有多種語(yǔ)言可以編譯為 class 字節(jié)碼,而不同語(yǔ)言的特性是不同的。比如 Java 字段類型一旦確定就不許變化,而 JavaScript 字段類型則更加靈活。這就意味著 class 字節(jié)碼和 JVM 層面必須對(duì)多種語(yǔ)言特性進(jìn)行支持,JVM 執(zhí)行層面各字段類型不完全等于 Java 代碼中的類型,JVM 執(zhí)行代碼的順序也不完全等于 Java 代碼中的順序。
要想了解 Java 代碼真正運(yùn)行期間發(fā)生了什么,我們需要了解 class 字節(jié)碼格式和 JVM 執(zhí)行流程。這兩者均在?JVM 規(guī)范[3]中有所定義。
我們?nèi)粘i_(kāi)發(fā)中讓人頭疼的問(wèn)題,在對(duì)字節(jié)碼和 JVM 有一定了解后都會(huì)煙消云散。比如:
?if (flag)?和?if (flag == true)?在字節(jié)碼層面是否有區(qū)別?有何區(qū)別??如下代碼在 try catch 不同代碼塊調(diào)用 return,函數(shù)最終返回返回值是什么?為什么會(huì)這樣?
// 此代碼參考《深入理解 Java 虛擬機(jī)》代碼清單 6-5public int inc() {int x;try {x = 1;return x;} catch (Exception e) {x = 2;return x;} finally {x = 3;}}
?對(duì)于重寫和重載方法,JVM 調(diào)用時(shí)如何定位到具體方法??對(duì)于多態(tài),JVM 又是如何實(shí)現(xiàn)?
關(guān)于字節(jié)碼解讀和 JVM 基本原理,我們有時(shí)間再繼續(xù)聊。
推薦資料
1.《深入理解 JVM 字節(jié)碼》 正如《重構(gòu)》一書(shū)是代碼重構(gòu)領(lǐng)域的圣經(jīng),此書(shū)也是國(guó)內(nèi)理解 JVM 的必讀之書(shū)。2.Java 語(yǔ)言和虛擬機(jī)規(guī)范官網(wǎng)[4]
References
[1]?Java 官網(wǎng):?https://docs.oracle.com/javase/specs/index.html[2]?GraalVM 官網(wǎng):?https://www.graalvm.org/[3]?JVM 規(guī)范:?https://docs.oracle.com/javase/specs/jvms/se17/html/index.html[4]?Java 語(yǔ)言和虛擬機(jī)規(guī)范官網(wǎng):?https://docs.oracle.com/javase/specs/index.html
