複製鏈接
請複製以下鏈接發送給好友

及時編譯程序

鎖定
及時編譯,又譯即時編譯、實時編譯,動態編譯的一種形式,是一種提高程序運行效率的方法。通常,程序有兩種運行方式:靜態編譯與動態直譯。靜態編譯的程序在執行前全部被翻譯為機器碼,而直譯執行的則是一句一句邊運行邊翻譯。
中文名
及時編譯程序
外文名
Just In Time compiler
範    疇
動態編譯
別    名
即時編譯
實時編譯
對    比
自適應動態編譯、本地代碼
開    銷
時間開銷、空間開銷

及時編譯程序程序簡介

即時編譯,又譯及時編譯、實時編譯,動態編譯的一種形式,是一種提高程序運行效率的方法。通常,程序有兩種運行方式:靜態編譯與動態直譯。靜態編譯的程序在執行前全部被翻譯為機器碼,而直譯執行的則是一句一句邊運行邊翻譯。

及時編譯程序即時編譯器

即時編譯器混合了這二者,一句一句編譯源代碼,但是會將翻譯過的代碼緩存起來以降低性能損耗。相對於靜態編譯代碼,即時編譯的代碼可以處理延遲綁定並增強安全性。即時編譯器有兩種類型,一是字節碼翻譯,二是動態編譯翻譯。

及時編譯程序對比

及時編譯程序JIT編譯

即just-in-timecompilation,狹義來説是當某段代碼即將第一次被執行時進行編譯,因而叫“即時編譯”。JIT編譯是動態編譯的一種特例。JIT編譯一詞後來被泛化,時常與動態編譯等價;但要注意廣義與狹義的JIT編譯所指的區別。

及時編譯程序自適應動態編譯

即adaptive dynamic compilation,也是一種動態編譯,但它通常執行的時機比JIT編譯遲,先讓程序“以某種式”先運行起來,收集一些信息之後再做動態編譯。這樣的編譯可以更加優化。

及時編譯程序本地代碼

程序中的代碼只有是熱點代碼時,才會編譯為本地代碼。
運行過程中會被即時編譯器編譯的“熱點代碼”有兩類:
1、被多次調用的方法。
2、被多次執行的循環體。
兩種情況,編譯器都是以整個方法作為編譯對象。 這種編譯方法因為編譯發生在方法執行過程之中,因此形象的稱之為棧上替換(On Stack Replacement,OSR),即方法棧幀還在棧上,方法就被替換了。

及時編譯程序JVM運行原理

在部分商用虛擬機中(如HotSpot),Java程序最初是通過解釋器(Interpreter)進行解釋執行的,當虛擬機發現某個方法或代碼塊的運行特別頻繁時,就會把這些代碼認定為“熱點代碼”。為了提高熱點代碼的執行效率,在運行時,虛擬機將會把這些代碼編譯成與本地平台相關的機器碼,並進行各種層次的優化,完成這個任務的編譯器稱為即時編譯器(Just In Time Compiler,下文統稱JIT編譯器)。
即時編譯器並不是虛擬機必須的部分,Java虛擬機規範並沒有規定Java虛擬機內必須要有即時編譯器存在,更沒有限定或指導即時編譯器應該如何去實現。但是,即時編譯器編譯性能的好壞、代碼優化程度的高低卻是衡量一款商用虛擬機優秀與否的最關鍵的指標之一,它也是虛擬機中最核心且最能體現虛擬機技術水平的部分。
由於Java虛擬機規範並沒有具體的約束規則去限制即使編譯器應該如何實現,所以這部分功能完全是與虛擬機具體實現相關的內容,如無特殊説明,我們提到的編譯器、即時編譯器都是指Hotspot虛擬機內的即時編譯器,虛擬機也是特指HotSpot虛擬機。 [1] 

及時編譯程序編譯的時間開銷

解釋器的執行,抽象的看是這樣的:輸入的代碼 -> [ 解釋器 解釋執行 ] -> 執行結果
而要JIT編譯然後再執行的話,抽象的看則是:輸入的代碼 -> [ 編譯器 編譯 ] -> 編譯後的代碼 -> [ 執行 ] -> 執行結果
説JIT比解釋快,其實説的是“執行編譯後的代碼”比“解釋器解釋執行”要快,並不是説“編譯”這個動作比“解釋”這個動作快。JIT編譯再怎麼快,至少也比解釋執行一次略慢一些,而要得到最後的執行結果還得再經過一個“執行編譯後的代碼”的過程。所以,對“只執行一次”的代碼而言,解釋執行其實總是比JIT編譯執行要快。

及時編譯程序編譯的空間開銷

對一般的Java方法而言,編譯後代碼的大小相對於字節碼的大小,膨脹比達到10x是很正常的。同上面説的時間開銷一樣,這裏的空間開銷也是,只有對執行頻繁的代碼才值得編譯,如果把所有代碼都編譯則會顯著增加代碼所佔空間,導致“代碼爆炸”。
參考資料
  • 1.    周志明. 深入理解Java虛擬機[M]. 機械工業出版社, 2013.