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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

66.javac 编译与 JIT 编译\编译过程\javac 编译\词法、语法分析\填充符号表\语义分析\字节码生成\JIT 编译

發(fā)布時(shí)間:2024/9/27 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 66.javac 编译与 JIT 编译\编译过程\javac 编译\词法、语法分析\填充符号表\语义分析\字节码生成\JIT 编译 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

66.javac 編譯與 JIT 編譯
66.1.編譯過程
66.2.javac 編譯
66.2.1.詞法、語法分析
66.2.2.填充符號(hào)表
66.2.3.語義分析
66.2.4.字節(jié)碼生成
66.3.JIT 編譯

66.javac 編譯與 JIT 編譯

66.1.編譯過程

不論是物理機(jī)還是虛擬機(jī),大部分的程序代碼從開始編譯到最終轉(zhuǎn)化成物理機(jī)的目標(biāo)代碼或虛擬機(jī)能執(zhí)行的指令集之前,都會(huì)按照如下圖所示的各個(gè)步驟進(jìn)行:

其中綠色的模塊可以選擇性實(shí)現(xiàn)。很容易看出,上圖中間的那條分支是解釋執(zhí)行的過程(即一條字節(jié)碼一條字節(jié)碼地解釋執(zhí)行,如 JavaScript),而下面的那條分支就是傳統(tǒng)編譯原理中從源代碼到目標(biāo)機(jī)器代碼的生成過程。

如今,基于物理機(jī)、虛擬機(jī)等的語言,大多都遵循這種基于現(xiàn)代經(jīng)典編譯原理的思路,在執(zhí)行前先對(duì)程序源碼進(jìn)行詞法解析和語法解析處理,把源碼轉(zhuǎn)化為抽象語法樹。對(duì)于一門具體語言的實(shí)現(xiàn)來說,詞法和語法分析乃至后面的優(yōu)化器和目標(biāo)代碼生成器都可以選擇獨(dú)立于執(zhí)行引擎,形成一個(gè)完整意義的編譯器去實(shí)現(xiàn),這類代表是 C/C++語言。也可以把抽象語法樹或指令流之前的步驟實(shí)現(xiàn)一個(gè)半獨(dú)立的編譯器,這類代表是 Java 語言。又或者可以把這些步驟和執(zhí)行引擎全部集中在一起實(shí)現(xiàn),如大多數(shù)的 JavaScript 執(zhí)行器。

66.2.javac 編譯

在 Java 中提到“編譯”,自然很容易想到 javac 編譯器將*.java文件編譯成為*.class文件的過程,這里的 javac 編譯器稱為前端編譯器,其他的前端編譯器還有諸如 Eclipse JDT 中的增量式編譯器 ECJ 等。相對(duì)應(yīng)的還有后端編譯器,它在程序運(yùn)行期間將字節(jié)碼轉(zhuǎn)變成機(jī)器碼(現(xiàn)在的 Java 程序在運(yùn)行時(shí)基本都是解釋執(zhí)行加編譯執(zhí)行),如 HotSpot 虛擬機(jī)自帶的 JIT(Just In Time Compiler)編譯器(分 Client 端和 Server 端)。另外,有時(shí)候還有可能會(huì)碰到靜態(tài)提前編譯器(AOT,Ahead Of Time Compiler)直接把*.java文件編譯成本地機(jī)器代碼,如 GCJ、Excelsior JET 等,這類編譯器我們應(yīng)該比較少遇到。
下面簡要說下 javac 編譯(前端編譯)的過程。

66.2.1.詞法、語法分析

詞法分析是將源代碼的字符流轉(zhuǎn)變?yōu)闃?biāo)記(Token)集合。單個(gè)字符是程序編寫過程中的的最小元素,而標(biāo)記則是編譯過程的最小元素,關(guān)鍵字、變量名、字面量、運(yùn)算符等都可以成為標(biāo)記,比如整型標(biāo)志 int 由三個(gè)字符構(gòu)成,但是它只是一個(gè)標(biāo)記,不可拆分。

語法分析是根據(jù)Token序列來構(gòu)造抽象語法樹的過程。抽象語法樹是一種用來描述程序代碼語法結(jié)構(gòu)的樹形表示方式,語法樹的每一個(gè)節(jié)點(diǎn)都代表著程序代碼中的一個(gè)語法結(jié)構(gòu),如 bao、類型、修飾符、運(yùn)算符等。經(jīng)過這個(gè)步驟后,編譯器就基本不會(huì)再對(duì)源碼文件進(jìn)行操作了,后續(xù)的操作都建立在抽象語法樹之上。

66.2.2.填充符號(hào)表

完成了語法分析和詞法分析之后,下一步就是填充符號(hào)表的過程。符號(hào)表是由一組符號(hào)地址和符號(hào)信息構(gòu)成的表格。符號(hào)表中所登記的信息在編譯的不同階段都要用到,在語義分析(后面的步驟)中,符號(hào)表所登記的內(nèi)容將用于語義檢查和產(chǎn)生中間代碼,在目標(biāo)代碼生成階段,黨對(duì)符號(hào)名進(jìn)行地址分配時(shí),符號(hào)表是地址分配的依據(jù)。

66.2.3.語義分析

語法樹能表示一個(gè)結(jié)構(gòu)正確的源程序的抽象,但無法保證源程序是符合邏輯的。而語義分析的主要任務(wù)是讀結(jié)構(gòu)上正確的源程序進(jìn)行上下文有關(guān)性質(zhì)的審查。語義分析過程分為標(biāo)注檢查和數(shù)據(jù)及控制流分析兩個(gè)步驟:
?標(biāo)注檢查步驟檢查的內(nèi)容包括諸如變量使用前是否已被聲明、變量和賦值之間的數(shù)據(jù)類型是否匹配等。
?數(shù)據(jù)及控制流分析是對(duì)程序上下文邏輯更進(jìn)一步的驗(yàn)證,它可以檢查出諸如程序局部變量在使用前是否有賦值、方法的每條路徑是否都有返回值、是否所有的受查異常都被正確處理了等問題。

66.2.4.字節(jié)碼生成

字節(jié)碼生成是 javac 編譯過程的最后一個(gè)階段。字節(jié)碼生成階段不僅僅是把前面各個(gè)步驟所生成的信息轉(zhuǎn)化成字節(jié)碼寫到磁盤中,編譯器還進(jìn)行了少量的代碼添加和轉(zhuǎn)換工作。 實(shí)例構(gòu)造器()方法和類構(gòu)造器()方法就是在這個(gè)階段添加到語法樹之中的(這里的實(shí)例構(gòu)造器并不是指默認(rèn)的構(gòu)造函數(shù),而是指我們自己重載的構(gòu)造函數(shù),如果用戶代碼中沒有提供任何構(gòu)造函數(shù),那編譯器會(huì)自動(dòng)添加一個(gè)沒有參數(shù)、訪問權(quán)限與當(dāng)前類一致的默認(rèn)構(gòu)造函數(shù),這個(gè)工作在填充符號(hào)表階段就已經(jīng)完成了)。

66.3.JIT 編譯

Java 程序最初是僅僅通過解釋器解釋執(zhí)行的,即對(duì)字節(jié)碼逐條解釋執(zhí)行,這種方式的執(zhí)行速度相對(duì)會(huì)比較慢,尤其當(dāng)某個(gè)方法或代碼塊運(yùn)行的特別頻繁時(shí),這種方式的執(zhí)行效率就顯得很低。于是后來在虛擬機(jī)中引入了 JIT 編譯器(即時(shí)編譯器),當(dāng)虛擬機(jī)發(fā)現(xiàn)某個(gè)方法或代碼塊運(yùn)行特別頻繁時(shí),就會(huì)把這些代碼認(rèn)定為“Hot Spot Code”(熱點(diǎn)代碼),為了提高熱點(diǎn)代碼的執(zhí)行效率,在運(yùn)行時(shí),虛擬機(jī)將會(huì)把這些代碼編譯成與本地平臺(tái)相關(guān)的機(jī)器碼,并進(jìn)行各層次的優(yōu)化,完成這項(xiàng)任務(wù)的正是 JIT編譯器。

現(xiàn)在主流的商用虛擬機(jī)(如Sun HotSpot、IBM J9)中幾乎都同時(shí)包含解釋器和編譯器(三大商用虛擬機(jī)之一的 JRockit 是個(gè)例外,它內(nèi)部沒有解釋器,因此會(huì)有啟動(dòng)相應(yīng)時(shí)間長之類的缺點(diǎn),但它主要是面向服務(wù)端的應(yīng)用,這類應(yīng)用一般不會(huì)重點(diǎn)關(guān)注啟動(dòng)時(shí)間)。二者各有優(yōu)勢(shì):當(dāng)程序需要迅速啟動(dòng)和執(zhí)行時(shí),解釋器可以首先發(fā)揮作用,省去編譯的時(shí)間,立即執(zhí)行;當(dāng)程序運(yùn)行后,隨著時(shí)間的推移,編譯器逐漸會(huì)返回作用,把越來越多的代碼編譯成本地代碼后,可以獲取更高的執(zhí)行效率。解釋執(zhí)行可以節(jié)約內(nèi)存,而編譯執(zhí)行可以提升效率。

HotSpot 虛擬機(jī)中內(nèi)置了兩個(gè)JIT編譯器:Client Complier 和 Server Complier,分別用在客戶端和服務(wù)端,目前主流的 HotSpot 虛擬機(jī)中默認(rèn)是采用解釋器與其中一個(gè)編譯器直接配合的方式工作。
運(yùn)行過程中會(huì)被即時(shí)編譯器編譯的“熱點(diǎn)代碼”有兩類:
?被多次調(diào)用的方法。
?被多次調(diào)用的循環(huán)體。

兩種情況,編譯器都是以整個(gè)方法作為編譯對(duì)象,這種編譯也是虛擬機(jī)中標(biāo)準(zhǔn)的編譯方式。要知道一段代碼或方法是不是熱點(diǎn)代碼,是不是需要觸發(fā)即時(shí)編譯,需要進(jìn)行 Hot Spot Detection(熱點(diǎn)探測(cè))。目前主要的熱點(diǎn) 判定方式有以下兩種:
?基于采樣的熱點(diǎn)探測(cè):采用這種方法的虛擬機(jī)會(huì)周期性地檢查各個(gè)線程的棧頂,如果發(fā)現(xiàn)某些方法經(jīng)常出現(xiàn)在棧頂,那這段方法代碼就是“熱點(diǎn)代碼”。這種探測(cè)方法的好處是實(shí)現(xiàn)簡單高效,還可以很容易地獲取方法調(diào)用關(guān)系,缺點(diǎn)是很難精確地確認(rèn)一個(gè)方法的熱度,容易因?yàn)槭艿骄€程阻塞或別的外界因素的影響而擾亂熱點(diǎn)探測(cè)。
?基于計(jì)數(shù)器的熱點(diǎn)探測(cè):采用這種方法的虛擬機(jī)會(huì)為每個(gè)方法,甚至是代碼塊建立計(jì)數(shù)器,統(tǒng)計(jì)方法的執(zhí)行次數(shù),如果執(zhí)行

次數(shù)超過一定的閥值,就認(rèn)為它是“熱點(diǎn)方法”。這種統(tǒng)計(jì)方法實(shí)現(xiàn)復(fù)雜一些,需要為每個(gè)方法建立并維護(hù)計(jì)數(shù)器,而且不能直接獲取到方法的調(diào)用關(guān)系,但是它的統(tǒng)計(jì)結(jié)果相對(duì)更加精確嚴(yán)謹(jǐn)。

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

方法調(diào)用計(jì)數(shù)器用來統(tǒng)計(jì)方法調(diào)用的次數(shù),在默認(rèn)設(shè)置下,方法調(diào)用計(jì)數(shù)器統(tǒng)計(jì)的并不是方法被調(diào)用的絕對(duì)次數(shù),而是一個(gè)相對(duì)的執(zhí)行頻率,即一段時(shí)間內(nèi)方法被調(diào)用的次數(shù)。

回邊計(jì)數(shù)器用于統(tǒng)計(jì)一個(gè)方法中循環(huán)體代碼執(zhí)行的次數(shù)(準(zhǔn)確地說,應(yīng)該是回邊的次數(shù),因?yàn)椴⒎撬械难h(huán)都是回邊),在字節(jié)碼中遇到控制流向后跳轉(zhuǎn)的指令就稱為“回邊”。

在確定虛擬機(jī)運(yùn)行參數(shù)的前提下,這兩個(gè)計(jì)數(shù)器都有一個(gè)確定的閥值,當(dāng)計(jì)數(shù)器的值超過了閥值,就會(huì)觸發(fā)JIT編譯。觸發(fā)了 JIT 編譯后,在默認(rèn)設(shè)置下,執(zhí)行引擎并不會(huì)同步等待編譯請(qǐng)求完成,而是繼續(xù)進(jìn)入解釋器按照解釋方式執(zhí)行字節(jié)碼,直到提交的請(qǐng)求被編譯器編譯完成為止(編譯工作在后臺(tái)線程中進(jìn)行)。當(dāng)編譯工作完成后,下一次調(diào)用該方法或代碼時(shí),就會(huì)使用已編譯的版本。

由于方法計(jì)數(shù)器觸發(fā)即時(shí)編譯的過程與回邊計(jì)數(shù)器觸發(fā)即時(shí)編譯的過程類似,因此這里僅給出方法調(diào)用計(jì)數(shù)器觸發(fā)即時(shí)編譯的流程:

javac 字節(jié)碼編譯器與虛擬機(jī)內(nèi)的 JIT 編譯器的執(zhí)行過程合起來其實(shí)就等同于一個(gè)傳統(tǒng)的編譯器所執(zhí)行的編譯過程。

與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的66.javac 编译与 JIT 编译\编译过程\javac 编译\词法、语法分析\填充符号表\语义分析\字节码生成\JIT 编译的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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