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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Java编译器优化与运行期优化技术浅析

發(fā)布時間:2025/3/15 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java编译器优化与运行期优化技术浅析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

一.java編譯器優(yōu)化

1. JVM的編譯器可以分為三個編譯器:?
????1)? 前端編譯器:把.java轉(zhuǎn)變?yōu)?class的過程。如Sun的Javac、Eclipse JDT中的增量式編譯器(ECJ)。?
????2)? JIT編譯器:把字節(jié)碼轉(zhuǎn)變?yōu)闄C(jī)器碼的過程,如HotSpot VM的C1、C2編譯器。?
????3)? AOT編譯器:靜態(tài)提前編譯器,直接將*.java文件編譯本地機(jī)器代碼的過程。

Javac編譯器

  Javac編譯器本身是由Java語言編寫的程序。

? ? ? ? ? ? ? ?

2.解析與填充符號表

解析步驟由parseFiles()方法完成,解析步驟包括了詞法分析和語法分析兩個過程。

  • 詞法分析與語法分析?
    詞法分析:將源代碼的字符流轉(zhuǎn)變?yōu)闃?biāo)記(Token)集合,單個字符是程序編寫過程的最小元素,而標(biāo)記則是編譯過程的最小元素,關(guān)鍵字、變量名、字面量、運(yùn)算符都可以成為標(biāo)記,在Javac的源碼中,詞法分析過程由com.sun.tools.javac.parser.Scanner類來實現(xiàn)。?
    語法分析是根據(jù)Token序列構(gòu)造抽象語法樹的過程,抽象語法樹是一種用來描述程序代碼語法結(jié)構(gòu)樹形表述方式。語法樹的每一個節(jié)點都代表著程序代碼中的一個語法結(jié)構(gòu),例如包、類型、修飾符、接口、返回值甚至代碼注釋都可以是一個語法結(jié)構(gòu)。語法分析過程由com.sun.tools.javac.parser.Parser類實現(xiàn),這個階段產(chǎn)出的抽象語法樹由com.sun.tools.javac.tree.JCTree類表示,經(jīng)過這個步驟之后,編譯器就基本不會再對源碼文件進(jìn)行操作了,后續(xù)的操作都是建立在抽象語法樹之上的。
  • 填充符號表?
    完成抽象語法樹之后,下一步就是填充符號表的過程,即enterTrees()方法。符號表是由一組符號地址和符號信息構(gòu)成的表格,類似于哈希表中K-V值對的形式。符號表中所登記的信息在編譯的不同階段都要用到。當(dāng)對符號名進(jìn)行地址分配時,符號表是地址分配的依據(jù)。填充過程由com.sun.tools.javac.comp.Enter類實現(xiàn)。

注解處理器

? ? ? ?JDK1.5之后,Java提供了對注解的支持,這些注解與普通的Java代碼一樣,在運(yùn)行期間發(fā)揮作用。?
  有了編譯器注解處理的標(biāo)準(zhǔn)API后,我們的代碼才有可能干涉編譯器的行為,由于語法樹中的任意元素,甚至包括代碼注釋都可以在插件之中訪問到,所以使用插入式注解處理器在功能上有很大的發(fā)揮空間。

語法分析與字節(jié)碼生成

  語法分析之后,編譯器獲得了程序代碼的抽象語法樹表示,語法樹能表示一個結(jié)構(gòu)正確的源代碼抽象。而語義分析的主要任務(wù)是對結(jié)構(gòu)上正確的源程序進(jìn)行上下文有關(guān)性質(zhì)的審查,如進(jìn)行類型審查。?
  在Javac編譯過程中,語法分析過程分為標(biāo)注檢查以及數(shù)據(jù)及控制流分析兩個步驟,分別對應(yīng)著attribute()和flow()方法完成。

  • 標(biāo)注檢查?
    標(biāo)注檢查步驟檢查的內(nèi)容包括諸如:變量使用前是否已被聲明、變量與賦值之間的數(shù)據(jù)類型是否能夠匹配等。此外,這個過程中還有一個重要的步驟稱為常量折疊。?
    標(biāo)注檢查步驟在Javac源碼中的實現(xiàn)類是com.xun.tools.javac.comp.Attr和com.sun.tools.javac.comp.Check類。
  • 數(shù)據(jù)及控制流分析?
    數(shù)據(jù)及控制流分析是對程序上下文邏輯更進(jìn)一步的驗證,它可以查出諸如程序員局部變量在使用前是否有賦值、方法的每條路徑是否都有返回值、是否所有的受查異常都被正確處理了等問題。編譯期的數(shù)據(jù)及控制流分析與類加載時的數(shù)據(jù)及數(shù)據(jù)流分析的目的基本上是一致的,但校驗范圍有所區(qū)別,有一些校驗項只有在編譯期或者運(yùn)行期才能進(jìn)行。如將局部變量聲明為final,對運(yùn)行期是沒有影響的,變量的不變性僅僅由編譯器在編譯期間保障,在Javac的源碼中,數(shù)據(jù)及控制流分析的入口是flow()方法,具體操作由com.sun.tools.javac.comp.Flow類來完成。
  • 解語法糖?
    語法糖是指在計算機(jī)語言中添加某種語法,這種語法對語言的功能并沒有影響,但是更方便程序員使用。?
    Java是一種“低糖語言”,常用的語法糖主要是之前提到的泛型、變長參數(shù)、自動裝箱/拆箱等。虛擬機(jī)運(yùn)行時不支持這些語法,它們在編譯期還原回簡單的基礎(chǔ)語法結(jié)構(gòu),這個過程稱為解語法糖。解語法糖的過程是由desuger()方法觸發(fā)的。
  • 字節(jié)碼生成?
    字節(jié)碼生成是Javac編譯過程的最后一個階段,由com.sun.tools.javac.jvm,Gen類來完成,字節(jié)碼生成階段不僅僅是把前面各個步驟所生成的信息(語法樹、符號表)轉(zhuǎn)化為字節(jié)碼寫入磁盤中,編譯器還進(jìn)行了少量代碼添加和轉(zhuǎn)換工作。?
    完成對語法樹的遍歷與調(diào)整之后,就會把填充了所有所需信息的符號表交給com.sun.tools.javac.jvm.ClassWriter類,由這個類的wrtieClass()方法輸出字節(jié)碼,生成最終的Class文件。

Java語法糖

泛型和類型擦除

  泛型是JDK1.5新增的特性,它的本質(zhì)是參數(shù)化類型的應(yīng)用,也就是說所操作的數(shù)據(jù)類型被指定為一個參數(shù),這種參數(shù)類型可以用于類、接口和方法的創(chuàng)建中,分別稱為泛型類、泛型接口和泛型方法。?
  與C#的泛型不一樣的是,Java的泛型只存在于程序源碼中,在編譯后的字節(jié)碼文件中,就已經(jīng)替換成原來的原生類型,也稱為裸類型,并且在相應(yīng)的地方插入了強(qiáng)制轉(zhuǎn)型代碼。因此,對于運(yùn)行期的Java語言來說,ArrayList與ArrayList就是同一個類,所以泛型技術(shù)實際上是Java語言的一顆語法糖,Java語言中的泛型實現(xiàn)方法稱為類型擦除,基于這種方法實現(xiàn)的泛型稱為偽泛型。故當(dāng)List和List作為參數(shù)時,擦除使得兩者的特征簽名變得一模一樣,有時可能導(dǎo)致?lián)碛性搩蓚€方法參數(shù)的方法無法重載。值得注意的是:當(dāng)出現(xiàn)上述的情況的時候,如果返回值不一樣的話,該兩個方法是可以存在于一個Class文件中的,總結(jié)一下,兩個方法如果有相同的名稱和特征簽名,但返回值不同,那它們也是合法地,可以共存于一個Class文件中。?
  擦除法所謂的擦除,僅僅是對方的Code屬性中的字節(jié)碼進(jìn)行擦除,實際上元數(shù)據(jù)中還是保留了泛型信息,這也是我們能通過反射手段取得參數(shù)化類型的根本依據(jù)。

自動裝箱、拆箱與遍歷循環(huán)

  自動裝箱、拆箱在編譯之后就被轉(zhuǎn)換成了相應(yīng)的包裝和還原方法,如Integer.valueOf()與Integer,intValue()方法,而遍歷循環(huán)則把代碼還原成了迭代器的實現(xiàn),這也是為何遍歷循環(huán)需要被遍歷類實現(xiàn)Iterable接口的原因。?
  包裝類的“==”運(yùn)算在不遇到算術(shù)運(yùn)算的情況下不會自動拆箱,以及它們equals()方法不處理數(shù)據(jù)轉(zhuǎn)型的關(guān)系。

條件編譯

  Java語言使用條件為常量的if語句,此代碼中的if語句不同于其他Java代碼,它在編譯階段就會被運(yùn)行,生成的字節(jié)碼之中只包含條件正確的部分。?
  Java語言中條件編譯的實現(xiàn),也是Java語言的一顆語法糖,根據(jù)布爾常量值的真假,編譯器將會把分支中不成立的代碼塊消除掉,這是在解語法糖階段實現(xiàn)的。

  Java語言中還有不少的其他語言糖,如內(nèi)部類、枚舉類、斷言語句、對枚舉和字符串的switch支持、try語句中定義和關(guān)閉資源等等。

?

二.運(yùn)行期優(yōu)化

? ? ? ?Java程序最初是通過解釋器(Interpreter)進(jìn)行解釋執(zhí)行的,當(dāng)虛擬機(jī)發(fā)現(xiàn)某個方法或代碼塊的運(yùn)行特別頻繁時,就會把這些代碼認(rèn)定為“熱點代碼”(Hot?Spot?Code)。?為了提高熱點代碼的執(zhí)行效率,在運(yùn)行時,虛擬機(jī)將會把這些代碼編譯成與本地平臺相關(guān)的機(jī)器碼,并進(jìn)行各種層次的優(yōu)化,完成這個任務(wù)的編譯器稱為即時編譯器(Just?In?Time?Compiler,下文中簡稱JIT編譯器)。

? ? ? ?當(dāng)程序運(yùn)行環(huán)境中內(nèi)存資源限制較大(如部分嵌入式系統(tǒng)中),可以使用解釋執(zhí)行節(jié)約內(nèi)存,反之可以使用編譯執(zhí)行來提升效率。

????????????????????

?

?

?

?

?

?

?

轉(zhuǎn)載于:https://my.oschina.net/JackieRiver/blog/1786431

總結(jié)

以上是生活随笔為你收集整理的Java编译器优化与运行期优化技术浅析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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