晚期(運行期)優(yōu)化

JIT:Java程序最初是由解釋器解釋執(zhí)行的驯杜,當虛擬機發(fā)現(xiàn)某個方法或代碼塊的運行特別頻繁時析砸,就會把這些“熱點代碼”編譯成機器碼,提高運行效率燃异。

1. 為什么要使用解釋器和編譯器并存坚嗜?

  • 當需要程序快速啟動和執(zhí)行的時候夯膀,可以使用解釋器,省去編譯時間苍蔬,立即執(zhí)行诱建。隨著時間推移,編譯器逐漸發(fā)揮作用碟绑,編譯為機器碼俺猿,可以提高效率。
  • 內存限制較大時格仲,解釋器執(zhí)行可以節(jié)約內存押袍,反之編譯器執(zhí)行可以提高效率。
  • 解釋器可以作為編譯器激進優(yōu)化的逃生門凯肋。

2. HotSpot的兩個不同的即時編譯器

  • Client Compiler:C1編譯器
  • Server Complier:C2編譯器
  1. interpreted mode:純解釋模式
  2. compiled mode:純編譯模式谊惭,無法編譯是解釋器還是會介入的
  3. mixed mode:解釋器和編譯器搭配

要想編譯出優(yōu)化程度高的代碼,需要時間成本侮东,所以虛擬機為了權衡圈盔,采用了分層編譯。采用分層編譯后悄雅,C1和C2同時工作习贫,C1獲得更高的編譯速度厉碟,C2獲得更好的編譯質量。

  • 第0層:程序解釋執(zhí)行,解釋器不開啟性能監(jiān)控氯葬,可觸發(fā)第1層編譯。
  • 第1層:C1編譯,簡單、可靠的優(yōu)化我碟,必要時加入性能監(jiān)控。
  • 第2層:啟動一些編譯耗時較長的優(yōu)化姚建,甚至根據(jù)性能監(jiān)控信息進行不可靠的激進優(yōu)化。

3. 編譯對象和觸發(fā)條件

熱點代碼

  1. 被多次調用的方法:整個方法為編譯對象吱殉,虛擬機標準的JIT編譯方式掸冤。
  2. 被多次執(zhí)行的循環(huán)體。雖然循環(huán)在方法體內友雳,但還是以整個方法為編譯對象稿湿,這種編譯方式為棧上替換,因為發(fā)生在方法執(zhí)行過程中押赊,方法幀還在棧上饺藤。

熱點探測

  1. 基于采樣的熱點探測:虛擬機周期性檢查各個線程的棧頂,如果某個方法經(jīng)常出現(xiàn)在棧頂流礁,說明是熱點涕俗。優(yōu)點:簡單高效、容易獲取方法調用關系神帅。缺點:很難精確確認一個方法的熱度再姑,容易受到線程阻塞或別的干擾。
  2. 基于計數(shù)器的熱點探測:虛擬機為每個方法甚至代碼塊建立計數(shù)器找御,統(tǒng)計方法執(zhí)行次數(shù)元镀。優(yōu)點:精確。缺點:成本高霎桅。

HotSpot使用的是第二種方法栖疑。它有兩類計數(shù)器:方法調用計數(shù)器和回邊計數(shù)器。

方法調用計數(shù)器:統(tǒng)計方法被調用的次數(shù)滔驶,默認閾值Client下1500次遇革,Server下10000次。

如果不做任何設置瓜浸,方法調用計數(shù)器統(tǒng)計的不是方法調用的絕對次數(shù)澳淑,而是一段時間內的次數(shù),超過一定時間后插佛,計數(shù)器會減半杠巡。這種衰減實在GC時順便進行的」涂埽可以用-XX:CounterDecay設置是否衰減氢拥,如果不衰減蚌铜,那么隨著時間的推移,總會達到次數(shù)進行編譯嫩海。

回邊計數(shù)器:統(tǒng)計一個方法中循環(huán)體執(zhí)行的次數(shù)冬殃。準確的說是回邊次數(shù),空循環(huán)不會回邊叁怪,只跳轉到自己审葬。
client模式閾值:方法調用計數(shù)器閾值OSR比率/100,OSR比率默認933奕谭。
server模式閾值:方法調用計數(shù)器閾值
(OSR比率 - 解釋器監(jiān)控比率)/100涣觉,OSR比率默認140,解釋器監(jiān)控比率默認33血柳。

回邊計數(shù)器沒有熱度衰減官册。

4. 一些編譯技術

  • 語言無關的經(jīng)典優(yōu)化技術之一:公共子表達式消除。
  • 語言相關的經(jīng)典優(yōu)化技術之一:數(shù)組范圍檢查消除难捌。
  • 最重要的優(yōu)化技術之一:方法內聯(lián)膝宁。
  • 最前沿的優(yōu)化技術之一:逃逸分析。

公共子表達式消除:如果一個表達式前面已經(jīng)計算過了根吁,后面表達式的變量也沒有變化過员淫,這個表達式就是公共子表達式,就沒有必要計算了击敌。

//javac不會作任何優(yōu)化满粗,但是JIT會優(yōu)化b * c
int d = (c * b) * 12 + a + +(a + b * c)

數(shù)組邊界檢查消除:Java在訪問數(shù)組元素時會自動進行上下界的范圍檢查,越界則拋出ArrayIndexOutOfBoundsException愚争,但是這也是一種性能負擔映皆。虛擬機根據(jù)情況在編譯器判斷是否可能越界,如果不越界執(zhí)行時就不需要檢查了轰枝。
類似情況還有NullPointException捅彻,除數(shù)為0異常等。

方法內聯(lián):編譯器最重要的優(yōu)化手段之一鞍陨,消除了方法調用的成本步淹,還為其它優(yōu)化建立了基礎。

  • 方法內聯(lián)不是代碼復制那么簡單诚撵,因為Java的方法(除了編譯期解析的)缭裆,編譯期都不能確定版本,運行期才可以寿烟。采用“類型繼承關系分析CHA”解決這一問題澈驼。

類型繼承關系分析CHA:基于整個應用,確定目前已加載的類中筛武,某個接口是否有多于一種實現(xiàn)缝其,某個類是否有子類挎塌,子類是否為抽象類等信息。

  1. 編譯器進行內聯(lián)時内边,如果是非虛方法榴都,那么直接內聯(lián)。如果遇到虛方法漠其,則查詢CHA是否有多個版本嘴高,如果只有一個,那么進行內聯(lián)(激進的和屎,需要逃生門)阳惹。如果后續(xù)虛擬機沒有加載其它類改變繼承關系,則一直內聯(lián)眶俩,否則退回解釋狀態(tài),或重新編譯快鱼。
  2. 如果CHA查詢出多個版本颠印,編譯器會使用內聯(lián)緩存。在未發(fā)生調用前抹竹,緩存為空线罕,發(fā)生調用后,緩存記錄下方法版本信息窃判,以后每次調用都比較版本钞楼,如果一直,內聯(lián)繼續(xù)袄琳,如果不一致询件,取消內聯(lián)。查找虛方法表唆樊。

逃逸分析:分析對象的動態(tài)作用域宛琅。不是代碼優(yōu)化手段,而是為其它手段提供依據(jù)逗旁。

  • 方法逃逸:一個對象被外部方法引用嘿辟,如傳參。
  • 線程逃逸:對象被外部線程訪問到片效,如賦值給類變量红伦。

如果證明一個對象不會逃逸,那么可以進行一些高效的優(yōu)化淀衣。

棧上分配:一般對象都在堆上分配昙读,各個線程共享,GC回收內存需要耗費時間膨桥。如果一個對象確定不會逃逸出方法箕戳,比如局部變量某残,那么分配在棧上就很舒服,可以隨棧幀出棧而銷毀陵吸。GC壓力減小玻墅。

同步消除:如果一個對象確定不是線程逃逸,那么就不會被其它線程訪問壮虫,就不存在競爭澳厢,完全可以消除同步。

標量替換:如果一個對象確定不會被外部訪問囚似,那么真正執(zhí)行的時候就不需要創(chuàng)建這個對象剩拢,改為在棧上創(chuàng)建對象拆散后的標量。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末饶唤,一起剝皮案震驚了整個濱河市徐伐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌募狂,老刑警劉巖办素,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異祸穷,居然都是意外死亡性穿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門雷滚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來需曾,“玉大人,你說我怎么就攤上這事祈远〈敉颍” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵车份,是天一觀的道長桑嘶。 經(jīng)常有香客問我,道長躬充,這世上最難降的妖魔是什么逃顶? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮充甚,結果婚禮上以政,老公的妹妹穿的比我還像新娘。我一直安慰自己伴找,他們只是感情好盈蛮,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著技矮,像睡著了一般抖誉。 火紅的嫁衣襯著肌膚如雪殊轴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天袒炉,我揣著相機與錄音旁理,去河邊找鬼。 笑死我磁,一個胖子當著我的面吹牛孽文,可吹牛的內容都是我干的。 我是一名探鬼主播夺艰,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼芋哭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了郁副?” 一聲冷哼從身側響起减牺,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎存谎,沒想到半個月后拔疚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡愕贡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了巷屿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片固以。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖嘱巾,靈堂內的尸體忽然破棺而出憨琳,到底是詐尸還是另有隱情,我是刑警寧澤旬昭,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布篙螟,位于F島的核電站,受9級特大地震影響问拘,放射性物質發(fā)生泄漏遍略。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一骤坐、第九天 我趴在偏房一處隱蔽的房頂上張望绪杏。 院中可真熱鬧,春花似錦纽绍、人聲如沸蕾久。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽僧著。三九已至履因,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間盹愚,已是汗流浹背栅迄。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留杯拐,地道東北人霞篡。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像端逼,于是被迫代替她去往敵國和親朗兵。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內容