Java編譯(一) Java三種編譯方式:前端編譯 JIT編譯 AOT編譯

       Java編譯(一) Java三種編譯方式:

前端編譯 JIT編譯 AOT編譯


        Java程序代碼需要編譯後才能在虛擬機中運行,編譯涉及到非常多的知識層面:編譯原理、語言規範、虛擬機規範、本地機器碼優化等;瞭解編譯過程有利於瞭解整個Java運行機制,不僅可以使得我們編寫出更優秀的代碼,而且還可以使得在JVM調優時更得心應手。

       下面我們先來看下Java體系中的三種編譯方式:前端編譯、即時編譯(JIT編譯)、靜態提前編譯(AOT編譯),先來了解它們各有什麼優點和缺點,再來看看主流的前端編譯+JIT編譯方式的運作過程。

1、前端編譯

       把Java源碼文件(.java)編譯成Class文件(.class)的過程;

       也即把滿足Java語言規範的程序轉化爲滿足JVM規範所要求格式的功能;

優點:

這階段的優化是指程序編碼方面的;

許多Java語法新特性("語法糖":泛型、內部類等等),是靠前端編譯器實現的,而不是依賴虛擬機;

編譯成的Class文件可以直接給JVM解釋器解釋執行,省去編譯時間,加快啓動速度;

缺點:

對代碼運行效率幾乎沒有任何優化措施;

解釋執行效率較低,所以需要結合下面的JIT編譯;    

前端編譯器:Oracle javac、Eclipse JDT中的增量式編譯器(ECJ)等;

2、後端編譯/即時(JIT)編譯

      通過Java虛擬機(JVM)內置的即時編譯器(Just In Time Compiler,JIT編譯器);在運行時把Class文件字節碼編譯成本地機器碼的過程;            

優點:

通過在運行時收集監控信息,把"熱點代碼"(Hot Spot Code)編譯成與本地平臺相關的機器碼,並進行各種層次的優化;

可以大大提高執行效率;

缺點:

收集監控信息影響程序運行;

編譯過程佔用程序運行時間(如使得啓動速度變慢);

編譯機器碼佔用內存;

JIT編譯器:HotSpot虛擬機的C1、C2編譯器等;

 

另外,JIT編譯速度及編譯結果的優劣,是衡量一個JVM性能的很重要指標;

所以對程序運行性能優化集中到這個階段;

也就是說可以對這個階段進行JVM調優;

3、靜態提前編譯(Ahead Of Time,AOT編譯)

       程序運行前,直接把Java源碼文件(.java)編譯成本地機器碼的過程;

優點:

編譯不佔用運行時間,可以做一些較耗時的優化,並可加快程序啓動;

把編譯的本地機器碼保存磁盤,不佔用內存,並可多次使用;

缺點:

因爲Java語言的動態性(如反射)帶來了額外的複雜性,影響了靜態編譯代碼的質量;

一般靜態編譯不如JIT編譯的質量,這種方式用得比較少;

靜態提前編譯器(AOT編譯器):JAOTC、GCJ、Excelsior JET、ART (Android Runtime)等;

 

關於ART (Android Runtime)模式:ART雖然主要通過AOT編譯支持Java的運行,但仍然帶有解釋器。

更多ART請參考:《ART沒有了Java虛擬機,能支持的了JNI嗎?比如Java和C++互調用,還有ART不用解釋器了那有沒有可能放棄Java呢?

《Android運行時ART簡要介紹和學習計劃》

更多AOT請參考:《Java中有類似於NGen的工具(AOT編譯器)嗎?

4、前端編譯+JIT編譯

到這裏,我們知道目前Java體系中主要還是採用前端編譯+JIT編譯的方式,如JDK中的HotSpot虛擬機。

前端編譯+JIT編譯方式的運作過程大體如下:

1、首先通過前端編譯把符合Java語言規範的程序代碼轉化爲滿足JVM規範所要求Class格式;

2、然後程序啓動時Class格式文件發揮作用,解釋執行,省去編譯時間,加快啓動速度;

3、針對Class解釋執行效率低的問題,在運行中收集性能監控信息,得知"熱點代碼";

4、JIT逐漸發揮作用,把越來越多的熱點代碼"編譯優化成本地代碼,提高執行效率;

 

      後面我們將分別去了解:前端編譯--把Java源碼文件編譯成Class文件的過程、Class文件的結構、以及JIT編譯--在運行時把Class文件字節碼編譯成本地機器碼的過程……

 

【參考資料】

1、《The Java Virtual Machine Specification》Java SE 8 Edition:https://docs.oracle.com/javase/specs/jvms/se8/html/index.html

2、《深入理解Java虛擬機:JVM高級特性與最佳實踐》第二版

3、實時Java,第2部分: 比較編譯技術--本地 Java 代碼的靜態編譯和動態編譯中的問題:www.ibm.com/developerworks/cn/java/j-rtj2/

4、很多文章都提到JVM對class文件的編譯,那麼編譯後的文件是在內存裏還是在哪?怎麼查看?:https://www.zhihu.com/question/52487484/answer/130785455

   5、Java中有類似於NGen的工具(AOT編譯器)嗎?:https://www.zhihu.com/question/29852046/answer/45917208

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