不要再問我Java程式是怎麼執行的了!

為何不是夢發表於2019-07-16

什麼是Java虛擬機器?

要弄明白Java程式的執行過程首先要了解一下Java虛擬機器

虛擬機器是一種抽象化的計算機,通過在實際的計算機上模擬模擬各種計算機功能來實現的。Java虛擬機器有自己完善的硬體架構,如處理器、堆疊、暫存器等,還具有相應的指令系統。Java虛擬機器遮蔽了與具體作業系統平臺相關的資訊,使得Java程式只需生成在Java虛擬機器上執行的目的碼(位元組碼),就可以在多種平臺上不加修改地執行。

Java虛擬機器(Java Virtual Machine簡稱JVM)是執行所有Java程式的抽象計算機,是Java語言的執行環境,它是Java 最具吸引力的特性之一。--百度百科

可以看到,Java虛擬機器是在原有計算機的基礎上虛擬出來的抽象計算機,提供Java程式的執行環境。JVM遮蔽了與具體作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機器上執行的目的碼(位元組碼),就可以在多種平臺上不加修改地執行。JVM是Java平臺無關的基礎,使Java程式能夠做到 “Write Once, Run Anywhere”。

Java程式執行過程

那有了Java程式的執行環境等一些列支援後,Java程式是如何做到從一個只有程式碼的.java原始檔變成計算機可執行的檔案的呢? 如下圖,是Java程式的執行過程。

 

大致過程就是,我們寫好的.java檔案(原始檔)被編譯器編譯後變成.class檔案(位元組碼),然後被JVM的類載入器載入到記憶體,通過位元組碼校驗器去做一些校驗,校驗通過後交由直譯器將位元組碼檔案解釋成計算機能夠識別的機器指令。

 

維基百科


位元組碼:位元組碼是已經經過編譯,但與特定機器碼無關,需要直譯器轉譯後才能成為機器碼的中間程式碼。


Java位元組碼:是Java虛擬機器執行的一種指令格式。


直譯器:是一種電腦程式,能夠把高階程式語言一行一行直接翻譯執行。直譯器不會一次把整個程式翻譯出來,只像一位“中間人”,每次執行程式時都要先轉成另一種語言再作執行,因此直譯器的程式執行速度比較緩慢。它每翻譯一行程式敘述就立刻執行,然後再翻譯下一行,再執行,如此不停地進行下去。它會先將原始碼翻譯成另一種語言,以供多次執行而無需再經編譯。其製成品無需依賴編譯器而執行,程式執行速度比較快

 

通過上圖我們知道Java程式的執行會經過一下幾個步驟:​編譯-->裝載位元組碼-->校驗位元組碼-->解釋位元組碼-->執行,然後我們看一下這幾個步驟具體執行過程,以及Java程式的執行過程對應到我們的實際操作:

1、編譯

在windows環境中,開啟命令視窗,切換到java檔案的目錄,使用 javac 命令,執行 javac xxx.java 把.java檔案編譯成.class檔案

2、裝載位元組碼

編譯好的.class檔案交給 JVM 執行,即使用java命令,執行java xxx(.class檔案的名稱,不帶字尾)。java命令將會啟動 JVM,並將後面的引數作為初始化類,通過 JVM 內的類載入器將位元組碼檔案裝載到記憶體中。

3、校驗位元組碼

類的載入是通過類載入器進行的,載入完後,先由位元組碼校驗器負責檢查那些無法執行的明顯有破壞性的操作。除了系統類之外,其他類都要被校驗。

校驗器執行的一些檢查:

  • 變數要在使用前初始化

  • 方法呼叫與物件引用型別之間要匹配

  • 訪問私有資料和方法的規則沒有被違反

  • 對本地變數的訪問都在執行的堆疊內

  • 執行時堆疊沒有溢位

如果這些檢查沒有通過,類最終不會被載入完成。

4、解釋位元組碼

JVM 把每一條要執行的位元組碼交給直譯器,翻譯成對應的機器語言,最終由作業系統執行。

JVM解釋執行位元組碼檔案就是JVM操作Java直譯器進行解釋執行位元組碼檔案的過程。

維基百科
機器語言:機器語言(machine language)是一種指令集的體系。這種指令集稱為機器程式碼(machine code),是計算機的CPU可直接解讀的資料。

結語

實際上JVM執行位元組碼檔案遠比這複雜,其中還包括即時編譯器、指令重排等優化。這裡只是對Java程式的執行過程做一個大致的介紹,讓Java程式設計師能夠明白自己寫的程式在JVM裡到底是如何執行的。如果要深入研究JVM的更多細節,建議大家去看書或其他資料。

相關文章