日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

词法分析器java_Java代码到底是如何编译成机器指令的。

發(fā)布時(shí)間:2023/12/1 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 词法分析器java_Java代码到底是如何编译成机器指令的。 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
原文地址:https://mp.weixin.qq.com/s/XH-JajAne0O7_yCYE5wBbg
作者:Hollis

在《Java代碼的編譯與反編譯》中,有過(guò)關(guān)于Java語(yǔ)言的編譯和反編譯的介紹。我們可以通過(guò)javac命令將Java程序的源代碼編譯成Java字節(jié)碼,即我們常說(shuō)的class文件。這是我們通常意義上理解的編譯。

但是,字節(jié)碼并不是機(jī)器語(yǔ)言,要想讓機(jī)器能夠執(zhí)行,還需要把字節(jié)碼翻譯成機(jī)器指令。這個(gè)過(guò)程是Java虛擬機(jī)做的,這個(gè)過(guò)程也叫編譯。是更深層次的編譯。

在編譯原理中,把源代碼翻譯成機(jī)器指令,一般要經(jīng)過(guò)以下幾個(gè)重要步驟:

根據(jù)完成任務(wù)不同,可以將編譯器的組成部分劃分為前端(Front End)與后端(Back End)。

前端編譯主要指與源語(yǔ)言有關(guān)但與目標(biāo)機(jī)無(wú)關(guān)的部分,包括詞法分析、語(yǔ)法分析、語(yǔ)義分析與中間代碼生成。
后端編譯主要指與目標(biāo)機(jī)有關(guān)的部分,包括代碼優(yōu)化和目標(biāo)代碼生成等。

我們可以把將.java文件編譯成.class的編譯過(guò)程稱(chēng)之為前端編譯。把將.class文件翻譯成機(jī)器指令的編譯過(guò)程稱(chēng)之為后端編譯。

Java中的前端編譯

前端編譯主要指與源語(yǔ)言有關(guān)但與目標(biāo)機(jī)無(wú)關(guān)的部分,包括詞法分析、語(yǔ)法分析、語(yǔ)義分析與中間代碼生成。

我們所熟知的javac的編譯就是前端編譯。除了這種以外,我們使用的很多IDE,如eclipse,idea等,都內(nèi)置了前端編譯器。主要功能就是把.java代碼轉(zhuǎn)換成.class代碼。

詞法分析

詞法分析階段是編譯過(guò)程的第一個(gè)階段。這個(gè)階段的任務(wù)是從左到右一個(gè)字符一個(gè)字符地讀入源程序,將字符序列轉(zhuǎn)換為標(biāo)記(token)序列的過(guò)程。這里的標(biāo)記是一個(gè)字符串,是構(gòu)成源代碼的最小單位。在這個(gè)過(guò)程中,詞法分析器還會(huì)對(duì)標(biāo)記進(jìn)行分類(lèi)。

詞法分析器通常不會(huì)關(guān)心標(biāo)記之間的關(guān)系(屬于語(yǔ)法分析的范疇),舉例來(lái)說(shuō):詞法分析器能夠?qū)⒗ㄌ?hào)識(shí)別為標(biāo)記,但并不保證括號(hào)是否匹配。

語(yǔ)法分析

語(yǔ)法分析的任務(wù)是在詞法分析的基礎(chǔ)上將單詞序列組合成各類(lèi)語(yǔ)法短語(yǔ),如“程序”,“語(yǔ)句”,“表達(dá)式”等等.語(yǔ)法分析程序判斷源程序在結(jié)構(gòu)上是否正確.源程序的結(jié)構(gòu)由上下文無(wú)關(guān)文法描述。

語(yǔ)義分析

語(yǔ)義分析是編譯過(guò)程的一個(gè)邏輯階段, 語(yǔ)義分析的任務(wù)是對(duì)結(jié)構(gòu)上正確的源程序進(jìn)行上下文有關(guān)性質(zhì)的審查,進(jìn)行類(lèi)型審查。語(yǔ)義分析是審查源程序有無(wú)語(yǔ)義錯(cuò)誤,為代碼生成階段收集類(lèi)型信息。

語(yǔ)義分析的一個(gè)重要部分就是類(lèi)型檢查。比如很多語(yǔ)言要求數(shù)組下標(biāo)必須為整數(shù),如果使用浮點(diǎn)數(shù)作為下標(biāo),編譯器就必須報(bào)錯(cuò)。再比如,很多語(yǔ)言允許某些類(lèi)型轉(zhuǎn)換,稱(chēng)為自動(dòng)類(lèi)型轉(zhuǎn)換。

中間代碼生成

在源程序的語(yǔ)法分析和語(yǔ)義分析完成之后,很多編譯器生成一個(gè)明確的低級(jí)的或類(lèi)機(jī)器語(yǔ)言的中間表示。該中間表示有兩個(gè)重要的性質(zhì): 1.易于生成; 2.能夠輕松地翻譯為目標(biāo)機(jī)器上的語(yǔ)言。

在Java中,javac執(zhí)行的結(jié)果就是得到一個(gè)字節(jié)碼,而這個(gè)字節(jié)碼其實(shí)就是一種中間代碼。

PS:著名的解語(yǔ)法糖操作,也是在javac中完成的。

Java中的后端編譯

首先,我們大家都知道,通常通過(guò) javac 將程序源代碼編譯,轉(zhuǎn)換成 java 字節(jié)碼,JVM 通過(guò)解釋字節(jié)碼將其翻譯成對(duì)應(yīng)的機(jī)器指令,逐條讀入,逐條解釋翻譯。很顯然,經(jīng)過(guò)解釋執(zhí)行,其執(zhí)行速度必然會(huì)比可執(zhí)行的二進(jìn)制字節(jié)碼程序慢很多。這就是傳統(tǒng)的JVM的解釋器(Interpreter)的功能。為了解決這種效率問(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),以備下次使用。

HotSpot虛擬機(jī)中內(nèi)置了兩個(gè)JIT編譯器:Client Complier和Server Complier,分別用在客戶(hù)端和服務(wù)端,目前主流的HotSpot虛擬機(jī)中默認(rèn)是采用解釋器與其中一個(gè)編譯器直接配合的方式工作。

當(dāng) JVM 執(zhí)行代碼時(shí),它并不立即開(kāi)始編譯代碼。首先,如果這段代碼本身在將來(lái)只會(huì)被執(zhí)行一次,那么從本質(zhì)上看,編譯就是在浪費(fèi)精力。因?yàn)閷⒋a翻譯成 java 字節(jié)碼相對(duì)于編譯這段代碼并執(zhí)行代碼來(lái)說(shuō),要快很多。第二個(gè)原因是最優(yōu)化,當(dāng) JVM 執(zhí)行某一方法或遍歷循環(huán)的次數(shù)越多,就會(huì)更加了解代碼結(jié)構(gòu),那么 JVM 在編譯代碼的時(shí)候就做出相應(yīng)的優(yōu)化。

在機(jī)器上,執(zhí)行java -version命令就可以看到自己安裝的JDK中JIT是哪種模式:

上圖是我的機(jī)器上安裝的jdk1.8,可以看到,他是Server Compile,但是,需要說(shuō)明的是,無(wú)論是Client Complier還是Server Complier,解釋器與編譯器的搭配使用方式都是混合模式,即上圖中的mixed mode。

熱點(diǎn)檢測(cè)

上面我們說(shuō)過(guò),要想觸發(fā)JIT,首先需要識(shí)別出熱點(diǎn)代碼。目前主要的熱點(diǎn)代碼識(shí)別方式是熱點(diǎn)探測(cè)(Hot Spot Detection),有以下兩種:

1、基于采樣的方式探測(cè)(Sample Based Hot Spot Detection) :周期性檢測(cè)各個(gè)線(xiàn)程的棧頂,發(fā)現(xiàn)某個(gè)方法經(jīng)常出險(xiǎn)在棧頂,就認(rèn)為是熱點(diǎn)方法。好處就是簡(jiǎn)單,缺點(diǎn)就是無(wú)法精確確認(rèn)一個(gè)方法的熱度。容易受線(xiàn)程阻塞或別的原因干擾熱點(diǎn)探測(cè)。

2、基于計(jì)數(shù)器的熱點(diǎn)探測(cè)(Counter Based Hot Spot Detection)。采用這種方法的虛擬機(jī)會(huì)為每個(gè)方法,甚至是代碼塊建立計(jì)數(shù)器,統(tǒng)計(jì)方法的執(zhí)行次數(shù),某個(gè)方法超過(guò)閥值就認(rèn)為是熱點(diǎn)方法,觸發(fā)JIT編譯。

在HotSpot虛擬機(jī)中使用的是第二種——基于計(jì)數(shù)器的熱點(diǎn)探測(cè)方法,因此它為每個(gè)方法準(zhǔn)備了兩個(gè)計(jì)數(shù)器:方法調(diào)用計(jì)數(shù)器和回邊計(jì)數(shù)器。

方法計(jì)數(shù)器。顧名思義,就是記錄一個(gè)方法被調(diào)用次數(shù)的計(jì)數(shù)器。

回邊計(jì)數(shù)器。是記錄方法中的for或者while的運(yùn)行次數(shù)的計(jì)數(shù)器。

編譯優(yōu)化

前面提到過(guò),JIT除了具有緩存的功能外,還會(huì)對(duì)代碼做各種優(yōu)化。說(shuō)到這里,不得不佩服HotSpot的開(kāi)發(fā)者,他們?cè)贘IT中對(duì)于代碼優(yōu)化真的算是面面俱到了。

這里簡(jiǎn)答提及幾個(gè)我覺(jué)得比較重要的優(yōu)化技術(shù),并不準(zhǔn)備直接展開(kāi),讀者感興趣的話(huà),我后面再寫(xiě)文章單獨(dú)介紹。

逃逸分析、 鎖消除、 鎖膨脹、 方法內(nèi)聯(lián)、 空值檢查消除、 類(lèi)型檢測(cè)消除、 公共子表達(dá)式消除。

總結(jié)

以上是生活随笔為你收集整理的词法分析器java_Java代码到底是如何编译成机器指令的。的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。