什么是編譯?
程序員寫(xiě)完代碼是.java文件蛇尚,我們的機(jī)器是不認(rèn)識(shí)的芽唇。需要通過(guò)JVM把字節(jié)碼翻譯成機(jī)器語(yǔ)言,而不同平臺(tái)安裝不同版本的JVM即可編譯成具有對(duì)應(yīng)平臺(tái)特性的機(jī)器語(yǔ)言取劫。
編譯步驟
前端編譯
我們所熟知的javac的編譯就是前端編譯匆笤。將.java文件編譯成.class文件
下面的步驟歌跟英語(yǔ)語(yǔ)句理解一樣
詞法分析
先分析每個(gè)單詞有沒(méi)有拼寫(xiě)錯(cuò)誤。
這里指找出其中我們定義好的關(guān)鍵字谱邪,找出規(guī)范化的Token流炮捧。
語(yǔ)法分析
語(yǔ)法有沒(méi)有錯(cuò)誤,比如主謂賓惦银。
這里指java語(yǔ)言規(guī)范(如在if后面是不是緊跟著一個(gè)布爾判斷表達(dá)式)咆课,形成一個(gè)符合java語(yǔ)言規(guī)范的抽象語(yǔ)法樹(shù)末誓。
語(yǔ)義分析
這段語(yǔ)句所表達(dá)的意思是否正確。
這里指將一些難懂的书蚪、復(fù)雜的語(yǔ)法轉(zhuǎn)化成更加簡(jiǎn)單的語(yǔ)法喇澡,結(jié)果形成最簡(jiǎn)單的語(yǔ)法(如將foreach轉(zhuǎn)換成for循環(huán)、注解等)殊校。形成一個(gè)注解過(guò)后的抽象語(yǔ)法樹(shù)晴玖,這個(gè)語(yǔ)法樹(shù)更為接近目標(biāo)語(yǔ)言的語(yǔ)法規(guī)則。
中間代碼
通過(guò)字節(jié)碼生產(chǎn)器將經(jīng)過(guò)注解的抽象語(yǔ)法樹(shù)轉(zhuǎn)化成符合jvm規(guī)范的字節(jié)碼
該中間代碼有兩個(gè)重要的性質(zhì):
- 易于生成
- 能夠輕松地翻譯為目標(biāo)機(jī)器上的語(yǔ)言
后端編譯
后端編譯主要指與目標(biāo)機(jī)有關(guān)的部分为流,包括代碼優(yōu)化和目標(biāo)代碼生成等呕屎。
這部分編譯主要是JVM通過(guò)解釋字節(jié)碼將其翻譯成對(duì)應(yīng)的機(jī)器指令,逐條讀入艺谆,逐條解釋翻譯成機(jī)器碼
JIT優(yōu)化
上面說(shuō)的后端編譯
榨惰,每次方法執(zhí)行JVM通過(guò)解釋字節(jié)碼將其翻譯成對(duì)應(yīng)的機(jī)器指令,逐條讀入静汤,逐條解釋翻譯成機(jī)器碼琅催。很顯然,經(jīng)過(guò)解釋執(zhí)行虫给,其執(zhí)行速度必然會(huì)比直接執(zhí)行的二進(jìn)制字節(jié)碼程序慢很多藤抡。為了解決這種效率問(wèn)題,引入了 JIT 技術(shù)抹估。
JAVA程序先通過(guò)解釋器進(jìn)行解釋執(zhí)行缠黍,當(dāng)JVM發(fā)現(xiàn)某個(gè)方法或代碼塊運(yùn)行特別頻繁的時(shí)候,就會(huì)認(rèn)為這是“熱點(diǎn)代碼”(Hot Spot Code)药蜻。然后JIT會(huì)把部分“熱點(diǎn)代碼”翻譯成本地機(jī)器相關(guān)的機(jī)器碼瓷式,并進(jìn)行優(yōu)化,然后再把翻譯后的機(jī)器碼緩存起來(lái)语泽,以備下次使用贸典。
優(yōu)化技術(shù)
- 公共子表達(dá)式消除
- 數(shù)組范圍檢查消除
- 方法內(nèi)聯(lián)
- 逃逸分析
上面優(yōu)化技術(shù),具體的不展開(kāi)了踱卵。因?yàn)楣ぷ魃蠜](méi)怎么用到過(guò)廊驼,只需要了解就行了