Java JVM虛擬機(jī)
在開(kāi)始這一部分內(nèi)容之前,我們先來(lái)看一下,在Java中,Java程序是如何運(yùn)行的,最后又是如何交給JVM托管的?
1.Java 程序運(yùn)行過(guò)程
作為一名 Java 程序員,你應(yīng)該知道,Java 代碼有很多種不同的運(yùn)行方式。比如說(shuō)可以在開(kāi)發(fā)工具中運(yùn)行,可以雙擊執(zhí)行 jar 文件運(yùn)行,也可以在命令行中運(yùn)行,甚至可以在網(wǎng)頁(yè)中運(yùn)行。當(dāng)然,這些執(zhí)行方式都離不開(kāi) JRE,也就是 Java 運(yùn)行時(shí)環(huán)境。
實(shí)際上,JRE 僅包含運(yùn)行 Java 程序的必需組件,包括 Java 虛擬機(jī)以及 Java 核心類庫(kù)等。我們 Java 程序員經(jīng)常接觸到的 JDK(Java 開(kāi)發(fā)工具包)同樣包含了 JRE,并且還附帶了一系列開(kāi)發(fā)、診斷工具。
然而,運(yùn)行 C++ 代碼則無(wú)需額外的運(yùn)行時(shí)。我們往往把這些代碼直接編譯成 CPU 所能理解的代碼格式,也就是機(jī)器碼。
Java 作為一門高級(jí)程序語(yǔ)言,它的語(yǔ)法非常復(fù)雜,抽象程度也很高。因此,直接在硬件上運(yùn)行這種復(fù)雜的程序并不現(xiàn)實(shí)。所以呢,在運(yùn)行 Java 程序之前,我們需要對(duì)其進(jìn)行一番轉(zhuǎn)換。
這個(gè)轉(zhuǎn)換具體是怎么操作的呢?當(dāng)前的主流思路是這樣子的,設(shè)計(jì)一個(gè)面向 Java 語(yǔ)言特性的虛擬機(jī),并通過(guò)編譯器將 Java 程序轉(zhuǎn)換成該虛擬機(jī)所能識(shí)別的指令序列,也稱 Java 字節(jié)碼。這里順便說(shuō)一句,之所以這么取名,是因?yàn)?Java 字節(jié)碼指令的操作碼(opcode)被固定為一個(gè)字節(jié)。
并且,我們同樣可以將其反匯編為人類可讀的代碼格式(如下圖的最右列所示)。不同的是,Java 版本的編譯結(jié)果相對(duì)精簡(jiǎn)一些。這是因?yàn)?Java 虛擬機(jī)相對(duì)于物理機(jī)而言,抽象程度更高。
Java 虛擬機(jī)可以由硬件實(shí)現(xiàn)[1],但更為常見(jiàn)的是在各個(gè)現(xiàn)有平臺(tái)(如 Windows_x64、Linux_aarch64)上提供軟件實(shí)現(xiàn)。這么做的意義在于,一旦一個(gè)程序被轉(zhuǎn)換成 Java 字節(jié)碼,那么它便可以在不同平臺(tái)上的虛擬機(jī)實(shí)現(xiàn)里運(yùn)行。這也就是我們經(jīng)常說(shuō)的“一次編寫,到處運(yùn)行”。
虛擬機(jī)的另外一個(gè)好處是它帶來(lái)了一個(gè)托管環(huán)境(Managed Runtime)。這個(gè)托管環(huán)境能夠代替我們處理一些代碼中冗長(zhǎng)而且容易出錯(cuò)的部分。其中最廣為人知的當(dāng)屬自動(dòng)內(nèi)存管理與垃圾回收,這部分內(nèi)容甚至催生了一波垃圾回收調(diào)優(yōu)的業(yè)務(wù)。
除此之外,托管環(huán)境還提供了諸如數(shù)組越界、動(dòng)態(tài)類型、安全權(quán)限等等的動(dòng)態(tài)檢測(cè),使我們免于書(shū)寫這些無(wú)關(guān)業(yè)務(wù)邏輯的代碼。
更多關(guān)于“java培訓(xùn)”的問(wèn)題,歡迎咨詢千鋒教育在線名師。千鋒教育多年辦學(xué),課程大綱緊跟企業(yè)需求,更科學(xué)更嚴(yán)謹(jǐn),每年培養(yǎng)泛IT人才近2萬(wàn)人。不論你是零基礎(chǔ)還是想提升,都可以找到適合的班型,千鋒教育隨時(shí)歡迎你來(lái)試聽(tīng)。