JVM和字節碼的關係

程序運行的兩種方式:靜態編譯和動態解釋

  • 靜態編譯的程序在執行前全部被翻譯爲機器碼
  • 動態解釋執行的則是一句一句邊運行邊翻譯

Java嚴格說來是“半解釋半編譯”型的語言

  • Java代碼首先由javac編譯器編譯成字節碼(ByteCode)。字節碼文件中JVM指令(也稱字節碼指令)是JVM唯一能夠識別的指令,JVM執行JVM指令時,通過JVM解釋器逐條讀取字節碼文件中JVM指令解釋爲機器碼執行。當某一方法調用次數達到即時編譯定義的閾值時,就會觸發即時編譯器JIT進行優化生成機器碼。
  • 字節碼文件和JVM指令的規範由JVM規範定義,JVM在不同的硬件平臺上需要有不同實現,以達到所謂“一次編寫,到處運行”的目標。
    解釋器的作用: 省去編譯的時間,使代碼立即執行。
    JIT編譯器的作用: 運行時將反覆執行的熱點代碼編譯爲二進制機器碼,避免解釋器反覆解釋,提高運行效率。

通過編譯原理理解java虛擬機編譯和解釋機制

在編譯原理中Javac編譯器被稱爲前端編譯器,而JIT編譯器被稱爲後端編譯器。
(1)在編譯原理中,通常將編譯分爲前端和後端。其中前端會對程序進行詞法分析、語法分析、語義分析,然後生成一箇中間表達形式(稱爲IR:Intermediate Representation)。後端再講這個中間表達形式進行優化,最終生成目標機器碼。
注意:在Java中,javac之後生成的就是中間表達形式(.class)
(2)JVM在執行時,首先會逐條讀取IR的指令來執行,這個過程就是解釋執行的過程。當某一方法調用次數達到即時編譯定義的閾值時,就會觸發即時編譯,這時即時編譯器會將IR進行優化,並生成這個方法的機器碼,後面再調用這個方法,就會直接調用機器碼執行,這個就是編譯執行的過程。


字節碼文件和JVM的關係

在這裏插入圖片描述

  • JVM虛擬機只能識別字節碼文件,任何語言只需要按照JVM規範中關於字節碼文件的標準生成字節碼文件,就可以在JVM中運行,而不僅僅只有java可以在JVM中運行,其他如Groovy、kotlin也可以在JVM編譯器中運行。
  • JVM指令是JVM規範中定義的指令集,在不同的平臺JVM指令對應了不同的實現,從而實現了一次編寫到處運行。
  • 不同的語言需要不同的前端編譯器(如javac、groovyc編譯器)等,JVM只和字節碼有關係,而與具體語言沒關係。

JVM如何實現跨平臺

不同CPU架構的彙編指令集不一致,jvm爲了實現跨平臺,在JVM規範裏定義了JVM指令集,針對同一指令在不同平臺架構做不同實現(既有C++代碼也內聯了彙編代碼),從而實現了跨平臺。

不同語言的源文件通過各自的編譯器按照JVM規範編譯爲字節碼文件,JVM加載到內存中,通過解釋器解釋或通過JIT即時編譯器將JVM指令翻譯爲二進制機器碼,交給CPU執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章