Java學(xué)習(xí)-程序編譯與代碼優(yōu)化

介紹

java代碼編譯器代表性的有三類
前端編譯器:我們熟知的javac就是前端編譯器
JIT編譯器:即時(shí)編譯器舱污,如hotspot的C1與C2編譯器也物,java的大部分優(yōu)化在這個(gè)編譯器里
AOT編譯器:這個(gè)是什么鬼夹界?

程序編譯

javac程序編譯分為三個(gè)過程:解析與填充符號(hào)表的過程,插入式注解處理器的注解處理過程司志,分析與字節(jié)碼生成過程例衍。具體未去探究

語(yǔ)法糖

語(yǔ)法糖的定義
語(yǔ)法糖是在計(jì)算機(jī)語(yǔ)言中添加的某種語(yǔ)法,這種語(yǔ)法對(duì)語(yǔ)言的功能并沒有影響恍箭,但是方便程序員使用刻恭。

1.java中的語(yǔ)法糖

1.1 泛型與泛型擦除

例如

 public static void method(List<String> list){
     System.out.println("測(cè)試");
 }
public static void method(List<Integer> list){
     System.out.println("測(cè)試");
 }

上述的這兩個(gè)方法具有相同的方法簽名,泛型擦除后都變成了

public static void method(List list){
    System.out.println("測(cè)試");  
}

所以如果最上面的兩個(gè)方法在同一個(gè)文件.java文件中扯夭,將無(wú)法通過編譯鳍贾,但是如果有不同的返回參數(shù)會(huì)通過編譯,這并不是說返回值屬于方法的特征簽名勉抓。能夠共存的原因是.class文件只要是描述符不相同的兩個(gè)方法就能共存贾漏。

1.2 自動(dòng)裝箱、拆箱藕筋、遍歷循環(huán)

自動(dòng)裝箱纵散,拆箱就不多說了。舉下面例子

  Integer i=100;

這個(gè)代碼將自動(dòng)調(diào)用

Integer i = Integer.valueOf(100);

 Integer i = 10; //裝箱 
 int t = i; //拆箱隐圾,實(shí)際上執(zhí)行了 int t = i.intValue();

遍歷循環(huán)
主要注意遍歷循環(huán)需要被遍歷的類實(shí)現(xiàn)Iterator接口伍掀。原因是在編譯后
遍歷循環(huán)把代碼還原成了迭代器的實(shí)現(xiàn)。

1.3 條件編譯

對(duì)于條件表達(dá)式中永遠(yuǎn)為false的語(yǔ)句暇藏,編譯器將不對(duì)條件覆蓋的代碼段生成字節(jié)碼蜜笤。
例如

public static void main(String[] args){
    if(true){
        System.out.println("one");
    }else{
        System.out.println("two");
   }
}

這個(gè)代碼編譯后的class文件反編譯的結(jié)果

public static void main(String[] args){
       System.out.println("one");
}

要注意的是只能使用條件為常量的if語(yǔ)句才能達(dá)到上述的效果

while(flase){
    System.out.print("www");
}

這個(gè)代碼將無(wú)法完成編譯

2 后期運(yùn)行優(yōu)化

2.1 解釋器和即時(shí)編譯器

當(dāng)程序需要迅速啟動(dòng)和執(zhí)行的時(shí)候,解釋器可以首先發(fā)揮作用盐碱,省去編譯時(shí)間把兔,隨著時(shí)間的推移沪伙,即時(shí)編譯器逐漸發(fā)揮作用,把越來越多的代碼編譯成本地代碼县好,之后可以獲得更高的執(zhí)行效率围橡。

2.2 JIT編譯器編譯對(duì)象及觸發(fā)條件

編譯對(duì)象:熱點(diǎn)代碼
哪些代碼會(huì)成為熱點(diǎn)代碼?
1.被多次調(diào)用的方法體缕贡;
2.被多次調(diào)用的循環(huán)體翁授。

如何確定代碼成為熱點(diǎn)代碼?
1.基于采樣的熱點(diǎn)探測(cè):
此方法會(huì)周期性檢查各個(gè)線程的棧頂晾咪,如果發(fā)現(xiàn)某個(gè)或某些方法經(jīng)常出現(xiàn)在棧頂收擦,那么這個(gè)方法就是熱點(diǎn)方法。此方法的缺點(diǎn)是很難精確地確認(rèn)一個(gè)方法的熱度谍倦,容易受到諸如線程阻塞等因素影響塞赂。

2.基于計(jì)數(shù)器的熱點(diǎn)探測(cè):
此方法會(huì)為每個(gè)方法甚至是代碼塊建立計(jì)數(shù)器,統(tǒng)計(jì)方法的執(zhí)行次數(shù)昼蛀,如果執(zhí)行次數(shù)超過一個(gè)閥值就認(rèn)為它是熱點(diǎn)方法减途。

HotSpot 使用的是第二種-基于技術(shù)其的熱點(diǎn)探測(cè),并且有兩類計(jì)數(shù)器:方法調(diào)用計(jì)數(shù)器(Invocation Counter )和回邊計(jì)數(shù)器

2.3 編譯過程

對(duì)于 Client 模式而言
它是一個(gè)簡(jiǎn)單快速的三段式編譯器曹洽,主要關(guān)注點(diǎn)在于局部的優(yōu)化,放棄了許多耗時(shí)較長(zhǎng)的全局優(yōu)化手段辽剧。
第一階段送淆,一個(gè)平臺(tái)獨(dú)立的前端將字節(jié)碼構(gòu)造成一種高級(jí)中間代碼表示(High-Level Intermediate Representaion , HIR)怕轿。在此之前偷崩,編譯器會(huì)在字節(jié)碼上完成一部分基礎(chǔ)優(yōu)化,如 方法內(nèi)聯(lián)撞羽,常量傳播等優(yōu)化阐斜。

第二階段,一個(gè)平臺(tái)相關(guān)的后端從 HIR 中產(chǎn)生低級(jí)中間代碼表示(Low-Level Intermediate Representation 诀紊,LIR)谒出,而在此之前會(huì)在 HIR 上完成另外一些優(yōu)化,如空值檢查消除邻奠,范圍檢查消除等笤喳,讓HIR 更為高效。

第三階段碌宴,在平臺(tái)相關(guān)的后端使用線性掃描算法(Linear Scan Register Allocation)在 LIR 上分配寄存器杀狡,做窺孔(Peephole)優(yōu)化,然后產(chǎn)生機(jī)器碼

對(duì)于 Server Compiler 模式而言
它是專門面向服務(wù)端的典型應(yīng)用贰镣,并為服務(wù)端的性能配置特別調(diào)整過的編譯器呜象,也是一個(gè)充分優(yōu)化過的高級(jí)編譯器膳凝,幾乎能達(dá)到 GNU C++ 編譯器使用-O2 參數(shù)時(shí)的優(yōu)化強(qiáng)度,它會(huì)執(zhí)行所有的經(jīng)典的優(yōu)化動(dòng)作恭陡,如 無(wú)用代碼消除(Dead Code Elimination)蹬音、循環(huán)展開(Loop Unrolling)、循環(huán)表達(dá)式外提(Loop Expression Hoisting)子姜、消除公共子表達(dá)式(Common Subexpression Elimination)祟绊、常量傳播(Constant Propagation)、基本塊沖排序(Basic Block Reordering)等哥捕,還會(huì)實(shí)施一些與 Java 語(yǔ)言特性密切相關(guān)的優(yōu)化技術(shù)牧抽,如范圍檢查消除(Range Check Elimination)、空值檢查消除(Null Check Elimination 遥赚,不過并非所有的空值檢查消除都是依賴編譯器優(yōu)化的扬舒,有一些是在代碼運(yùn)行過程中自動(dòng)優(yōu)化 了)等。另外凫佛,還可能根據(jù)解釋器或Client Compiler 提供的性能監(jiān)控信息讲坎,進(jìn)行一些不穩(wěn)定的激進(jìn)優(yōu)化,如 守護(hù)內(nèi)聯(lián)(Guarded Inlining)愧薛、分支頻率預(yù)測(cè)(Branch Frequency Prediction)等晨炕。

Server Compiler 編譯器可以充分利用某些處理器架構(gòu),如(RISC)上的大寄存器集合毫炉。從即時(shí)編譯的角度來看瓮栗, Server Compiler 無(wú)疑是比較緩慢的,但它的便以速度仍遠(yuǎn)遠(yuǎn)超過傳統(tǒng)的靜態(tài)優(yōu)化編譯器瞄勾,而且它相對(duì)于 Client Compiler編譯輸出的代碼質(zhì)量有所提高费奸,可以減少本地代碼的執(zhí)行時(shí)間,從而抵消了額外的編譯時(shí)間開銷进陡,所以也有很多非服務(wù)端的應(yīng)用選擇使用 Server 模式的虛擬機(jī)運(yùn)行愿阐。

2.4 編譯優(yōu)化技術(shù)

2.4.1 公共子表達(dá)式消除

如 int d=(cb)12+a +(a+bc)
變成 int d=e
12+a+(a+e),經(jīng)過代數(shù)化簡(jiǎn)后int d=e13+a2

2.4.2 數(shù)組邊界檢查消除

在虛擬機(jī)的執(zhí)行子系統(tǒng)中趾疚,每次數(shù)組元素的讀寫都帶有一次隱含的條件判定操作缨历。對(duì)于擁有大量數(shù)組訪問的代碼,這也是一種性能負(fù)擔(dān)盗蟆。無(wú)論如何戈二,為了安全,數(shù)組的邊界檢查是必須要做的喳资,但是數(shù)組邊界檢查是不是必須在運(yùn)行期間一次不漏的檢查則是可以“商量”的事情觉吭。
如foo[3] 只要在編譯期根據(jù)數(shù)據(jù)流分析來確定foo.length的值,并判斷下標(biāo)3沒有越界仆邓,執(zhí)行的時(shí)候就不需要判斷了鲜滩。
還有如果編譯器能通過數(shù)據(jù)流分析判定循環(huán)變量的取值范圍永遠(yuǎn)在[0,foo.length)之間伴鳖,那么整個(gè)循環(huán)就可以把數(shù)組的上下界檢查消除。

2.4.3 方法內(nèi)聯(lián)

存在的問題
對(duì)于虛方法徙硅,編譯期間無(wú)法確定使用方法的哪個(gè)版本
解決方案
類型繼承關(guān)系分析(CHA)
如果是非虛方法榜聂,則直接進(jìn)行內(nèi)聯(lián)即可。如果CHA查詢出來的結(jié)果有多個(gè)版本的目標(biāo)方法嗓蘑,則通過內(nèi)聯(lián)緩存做最后一次努力须肆。
內(nèi)聯(lián)緩存工作原理
在未發(fā)生方法調(diào)用之前,內(nèi)聯(lián)緩存狀態(tài)是空的桩皿,當(dāng)?shù)谝淮握{(diào)用發(fā)生時(shí)豌汇,緩存記錄下方法的接受者版本信息,并且每次運(yùn)行方法調(diào)用都比較接受者的版本泄隔,如果一致拒贱,內(nèi)聯(lián)可以一致使用下去,如果發(fā)現(xiàn)不一致就要取消內(nèi)聯(lián)查找虛方法表進(jìn)行方法分派佛嬉。

2.4.4 逃逸分析(不成熟)

棧上分配逻澳,同步消除(鎖消除),標(biāo)量替換

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末暖呕,一起剝皮案震驚了整個(gè)濱河市斜做,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌湾揽,老刑警劉巖陨享,帶你破解...
    沈念sama閱讀 212,080評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異钝腺,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)赞厕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門艳狐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人皿桑,你說我怎么就攤上這事毫目。” “怎么了诲侮?”我有些...
    開封第一講書人閱讀 157,630評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵镀虐,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我沟绪,道長(zhǎng)刮便,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,554評(píng)論 1 284
  • 正文 為了忘掉前任绽慈,我火速辦了婚禮恨旱,結(jié)果婚禮上辈毯,老公的妹妹穿的比我還像新娘。我一直安慰自己搜贤,他們只是感情好谆沃,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著仪芒,像睡著了一般唁影。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上掂名,一...
    開封第一講書人閱讀 49,856評(píng)論 1 290
  • 那天据沈,我揣著相機(jī)與錄音,去河邊找鬼铆隘。 笑死卓舵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的膀钠。 我是一名探鬼主播掏湾,決...
    沈念sama閱讀 39,014評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼肿嘲!你這毒婦竟也來了融击?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,752評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤雳窟,失蹤者是張志新(化名)和其女友劉穎尊浪,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體封救,經(jīng)...
    沈念sama閱讀 44,212評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拇涤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了誉结。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鹅士。...
    茶點(diǎn)故事閱讀 38,687評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖惩坑,靈堂內(nèi)的尸體忽然破棺而出掉盅,到底是詐尸還是另有隱情,我是刑警寧澤以舒,帶...
    沈念sama閱讀 34,347評(píng)論 4 331
  • 正文 年R本政府宣布趾痘,位于F島的核電站,受9級(jí)特大地震影響蔓钟,放射性物質(zhì)發(fā)生泄漏永票。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評(píng)論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瓦侮。 院中可真熱鬧艰赞,春花似錦、人聲如沸肚吏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)罚攀。三九已至党觅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間斋泄,已是汗流浹背杯瞻。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留炫掐,地道東北人魁莉。 一個(gè)月前我還...
    沈念sama閱讀 46,406評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像募胃,于是被迫代替她去往敵國(guó)和親旗唁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容