熱點代碼:
程序最初通過解釋器進(jìn)行解釋執(zhí)行的,當(dāng)虛擬機發(fā)現(xiàn)某個方法或代碼塊的運行特別頻繁時,就把這些代碼認(rèn)定為“熱點代碼”。
JIT編譯器
把熱點代碼編譯成與本地平臺相關(guān)的機器碼,并進(jìn)行各層次的優(yōu)化,完成這個任務(wù)的編譯器稱為即時編譯器。也就是JIT編譯器。
解釋器與編譯器并存
當(dāng)程序需要迅速啟動和執(zhí)行時,解釋器首先發(fā)揮作用,立即執(zhí)行。隨著時間推移,編譯器把代碼編譯成本地代碼之后,可以獲取更高的執(zhí)行效率。當(dāng)內(nèi)存資源限制較大時,使用解釋器執(zhí)行節(jié)約內(nèi)存,反之可以使用編譯器提升效率。
解釋器預(yù)編譯期搭配使用的方式在虛擬機稱為“混合模式(Mixed Mode)”
-Xint:設(shè)置強制運行于“解釋模式(Interpreted Mode)”,編譯器不介入。
-Xcomp:設(shè)置強制運行于“編譯模式”,優(yōu)先采用編譯方式執(zhí)行,編譯無法進(jìn)行時,使用解釋器。
運行模式
Client模式和Server模式??梢允褂?client或-server參數(shù)設(shè)置。
分層編譯:
第0層,程序解釋執(zhí)行,解釋器不開啟性能監(jiān)控功能,可觸發(fā)第一層編譯
第1層,也稱為C1編譯,將字節(jié)碼編譯為本地代碼,如有必有加入性能監(jiān)控的邏輯。
第2層(或2層以上),也稱為C2編譯,將字節(jié)碼編譯為本地代碼,但是會啟用一些編譯耗時較長的優(yōu)化,甚至?xí)鶕?jù)性能監(jiān)控信息進(jìn)行一些不可靠的激進(jìn)優(yōu)化。
觸發(fā)條件
熱點代碼被編譯時,分為兩種情況,當(dāng)方法調(diào)用觸發(fā)編譯時,以整個方法作為編譯對象,也是標(biāo)準(zhǔn)的JIT編譯方式;當(dāng)是循環(huán)體被多次調(diào)用時,盡管編譯動作是由循環(huán)體觸發(fā),單編譯器仍然會編譯整個方法,由于發(fā)生在方法執(zhí)行過程中,稱之為棧上替換。
熱點代碼方法:
1.基于采樣的熱點探測:周期性檢查各個線程的棧頂,如果發(fā)現(xiàn)某個方法經(jīng)常出現(xiàn)在棧頂,那這個方法就是“熱點方法”。
2.基于計數(shù)器的熱點探測:為每個方法建立計數(shù)器,統(tǒng)計方法的執(zhí)行次數(shù),如果執(zhí)行次數(shù)超過一定的閾值就認(rèn)為是“熱點方法”。
HotSpot如何探測熱點代碼?
HotSpot才有基于計數(shù)器的熱點探測,為每個方法準(zhǔn)備了方法調(diào)用計數(shù)器以及回邊計數(shù)器。
方法調(diào)用計數(shù)器:
Client模式下默認(rèn)閾值為1500,Server下為10000,可使用-XX:CompileThreshold設(shè)置。
當(dāng)超過一定時間限度,方法的調(diào)用次數(shù)不足以交給即時編譯器編譯,方法的調(diào)用計數(shù)器就會減少一半,稱為方法調(diào)用計數(shù)器的熱度衰減,這段時間稱為此方法統(tǒng)計的半衰周期。衰減的動作是在垃圾收集時進(jìn)行的,可使用-XX:-UseConterDecay關(guān)閉熱度衰減??梢允褂?XX:CounterHalfLifeTime設(shè)置半衰周期時間,單位秒。
回邊計數(shù)器:
統(tǒng)計一個方法中循環(huán)體代碼執(zhí)行的次數(shù),在字節(jié)碼中遇到控制流向后跳轉(zhuǎn)的指令稱為回邊。
-XX:OnStackReplacePercentage:設(shè)置參數(shù)間接調(diào)整回邊計數(shù)器閾值
Client-->方法調(diào)用計數(shù)器閾值??OSR 比率(OnStackReplacePercentage)/100。OnStackReplacePercentage默認(rèn)是933
Server-->方法調(diào)用計數(shù)器閾值??(OSR比率(OnStackReplacePercentage)-解釋器監(jiān)控比率(InterpreterProfilePercentage))/100,InterpreterProfilePercentage默認(rèn)為33,OnStackReplacePercentage默認(rèn)是140


