凡是接觸過 Java 的人都知道 JRE 的概念,即 Java 運行時環境( Java Runtime Environment ),因為它是運行 Java 程序必不可少的(除非程序用 GCJ 等編譯,但我懷疑這樣處理后還能不能稱之為“ Java 程序”了)。
Java 喊出的帶有標志性的口號“ Write Once , Run Anywhere (一次編寫,到處運行)”(記得某老師給俺們上課講到這里時還不忘幽一默:到處運行?沒有計算機就運行不了……),正是建立在 JRE 的基礎之上。何以實現?就是在 Java 應用程序和操作系統之間增加了一虛擬層—— JRE 。程序源代碼不是直接編譯、鏈接成機器代碼,而是先轉化到字節碼( bytecode )這種特殊的中間形式,字節碼再轉換成機器碼或系統調用。前者是傳統的編譯方法,生成的機器代碼就不可避免地跟特殊的操作系統和特殊的機器結構相關,很多裝雙系統的用戶無法在 Linux 運行 Windows 下的大型游戲,心里那個郁悶(于是很多虛擬軟件和模擬程序應運而生)。而 Java 程序的字節碼文件可以放到任意裝有 JRE 的計算機運行,再由不同 JRE 的將它們轉化成相應的機器代碼,這就實現了 Java 程序的可移植性。這樣程序員也不用去關心程序運行的具體環境,而可以專心編寫軟件。這種分層抽象、隱藏細節的思想在計算機科學中處處可見,比如機器組織結構的設計、網絡協議的實現等。 Pascal 語言的發明者 Niklaus Wirth ,就富有預見性地指出應該有這樣一種可移植的語言,其生成的中間代碼可以在一臺假想的機器( a hypothetical machine )上運行。而 Java 虛擬機( Java virtual machine 或 JVM )就是這樣的一臺機器,它模擬實際處理器的結構,解釋字節碼。怎么一會說是 JRE ,一會兒又成了 JVM ,兩者是否同物不同名?
回答是否定的。
JVM 是 Java 平臺的基礎,和實際的機器一樣,它也有自己的指令集,并且在運行時操作不同的內存區域。 JVM 通過抽象操作系統和 CPU 結構,提供了一種與平臺無關的代碼執行方法,即與特殊的實現方法、主機硬件、主機操作系統無關。但是在一些小的方面, JVM 的實現也是互不相同的,比如垃圾回收算法,線程調度算法(可能不同 OS 有不同的實現)。 JVM 的主要工作是解釋自己的指令集(即字節碼)到 CPU 的指令集或 OS 的系統調用,保護用戶免被惡意程序騷擾。 JVM 對上層的 Java 源文件是不關心的,它關注的只是由源文件生成的類文件( class file )。類文件的組成包括 JVM 指令集,符號表以及一些補助信息。
而 JRE 是 Sun 公司發布的一個更大的系統,它里面就有一個 JVM 。 JRE 就與具體的 CPU 結構和操作系統有關,我們從 Sun 下載 JRE 的時候就看到了不同的各種版本。同 JVM 一起組成 JRE 的還有一些 API (如 awt , swing 等)。 JRE 是運行 Java 程序必不可少的。
Over