熱點(diǎn)代碼探測(cè)確定何時(shí)JIT

JIT編譯器

概念解釋:

  • Java語(yǔ)言的"編譯器"其實(shí)是一段"不確定"的操作過(guò)程,因?yàn)樗赡苁侵敢粋€(gè)前端編譯器(其實(shí)叫"編譯器的前端"更準(zhǔn)確一些)把.java文件轉(zhuǎn)變成.class文件的過(guò)程。
  • 也可能是指虛擬機(jī)的后端運(yùn)行期編譯器(JIT編譯器,Just In Time Compiler)把字節(jié)碼轉(zhuǎn)變成機(jī)器碼的過(guò)程。
  • 還可能是指使用靜態(tài)提前編譯器(AOT 編譯器,Ahead Of Time Compiler)直接把.java文件編譯成本地機(jī)器代碼的過(guò)程。

前端編譯器: Sun的Javac、Eclipse JDT中的增量式編譯器(ECT)。
JIT 編譯器: HotSpot VM的C1、C2編譯器。
AOT 編譯器: GNU Compiler for the Java (GCJ)、Excelsior JET。

熱點(diǎn)代碼及探測(cè)方式

當(dāng)然是否需要啟動(dòng)JIT編譯器將字節(jié)碼直接編譯為對(duì)應(yīng)平臺(tái)的本地機(jī)器指令,則需要根據(jù)代碼被調(diào)用執(zhí)行的頻率而定。關(guān)于那些需要被編譯為本地代碼的字節(jié)碼,也被稱(chēng)之為"熱點(diǎn)代碼",JIT編譯器在運(yùn)行時(shí)會(huì)針對(duì)那些頻繁被調(diào)用的"熱點(diǎn)代碼"做出深度優(yōu)化,將其直接編譯為對(duì)應(yīng)平臺(tái)的本地機(jī)器指令,以此提升Java程序的執(zhí)行性能。

  • 一個(gè)被多次調(diào)用的方法,或者是一個(gè)方法體內(nèi)部循環(huán)次數(shù)較多的循環(huán)體都可以被稱(chēng)之為"熱點(diǎn)代碼",因此都可以通過(guò)JIT編譯器編譯為本地機(jī)器指令。由于這種編譯方式發(fā)生在方法的執(zhí)行過(guò)程中,因此也被稱(chēng)之為棧上替換,或簡(jiǎn)稱(chēng)為OSR(On Stack Replacement)編譯。
  • 一個(gè)方法究竟要被調(diào)用多少次,或者一個(gè)循環(huán)體究竟需要執(zhí)行多少次循環(huán)才可以達(dá)到這個(gè)標(biāo)準(zhǔn)?必然需要一個(gè)明確的閾值,JIT編譯器才會(huì)將這些"熱點(diǎn)代碼"編譯為本地機(jī)器指令執(zhí)行。這里主要依靠熱點(diǎn)探測(cè)功能
  • 目前HotSpot VM所采用的熱點(diǎn)探測(cè)方式是基于計(jì)數(shù)器的熱點(diǎn)探測(cè)。
  • 采用基于計(jì)數(shù)器的熱點(diǎn)探測(cè),HotSpot VM將會(huì)為每一個(gè)方法都建立2個(gè)不同類(lèi)型的計(jì)數(shù)器,分別為方法調(diào)用計(jì)數(shù)器(Invocation Counter)和回邊計(jì)數(shù)器(Back Edge Counter)。
    • 方法調(diào)用計(jì)數(shù)器用于統(tǒng)計(jì)方法的調(diào)用次數(shù)
    • 回邊計(jì)數(shù)器則用于統(tǒng)計(jì)循環(huán)體執(zhí)行的循環(huán)次數(shù)

方法調(diào)用計(jì)數(shù)器

  • 這個(gè)計(jì)數(shù)器就用于統(tǒng)計(jì)方法被調(diào)用的次數(shù),它的默認(rèn)閾值在Client模式下是1500次,在Server模式下是10000次。超過(guò)這個(gè)閾值,就會(huì)觸發(fā)JIT編譯。
  • 這個(gè)閾值可以通過(guò)虛擬機(jī)參數(shù)-XX:CompileThreshold來(lái)人為設(shè)定。
  • 當(dāng)一個(gè)方法被調(diào)用時(shí),會(huì)先檢查該方法是否存在被JIT編譯過(guò)的版本,如果存在,則優(yōu)先使用編譯后的本地代碼來(lái)執(zhí)行。吐過(guò)不存在已被編譯過(guò)的版本,則將此方法的調(diào)用計(jì)數(shù)器值加1,然后判斷方法調(diào)用計(jì)數(shù)器與回邊計(jì)數(shù)器之和是否超過(guò)方法調(diào)用計(jì)數(shù)器的閾值。如果已超過(guò)閾值,那么將會(huì)向即時(shí)編譯器提交一個(gè)該方法的代碼編譯請(qǐng)求。
熱度衰減
  • 如果不做任何設(shè)置,方法調(diào)用計(jì)數(shù)器統(tǒng)計(jì)的并不是方法被調(diào)用的絕對(duì)次數(shù),而是一個(gè)相對(duì)的執(zhí)行頻率,即一段時(shí)間之內(nèi)方法被調(diào)用的次數(shù)。當(dāng)超過(guò)一定的時(shí)間限度,如果方法的調(diào)用次數(shù)仍然不足以讓它提交給即時(shí)編譯器編譯,那這個(gè)方法的調(diào)用計(jì)數(shù)器就會(huì)被減少一半,這個(gè)過(guò)程稱(chēng)為方法調(diào)用計(jì)數(shù)器熱度的衰減(Counter Decay),而這段時(shí)間就稱(chēng)為此方法統(tǒng)計(jì)的半衰周期(Counter Half Life Time)。
  • 進(jìn)行熱度衰減的動(dòng)作是虛擬機(jī)進(jìn)行垃圾收集時(shí)順便進(jìn)行的,可以使用虛擬機(jī)參數(shù)-XX:-UseCounterDecay來(lái)關(guān)閉熱度衰減,讓方法計(jì)數(shù)器統(tǒng)計(jì)方法調(diào)用的絕對(duì)次數(shù),這樣,只要系統(tǒng)運(yùn)行時(shí)間夠長(zhǎng),絕大部分方法都會(huì)被編譯成本地代碼。
  • 另外,可以使用-XX:CounterHalfLifeTime參數(shù)設(shè)置半衰周期的時(shí)間,單位是秒。

回邊計(jì)數(shù)器

它的作用是統(tǒng)計(jì)一個(gè)方法中循環(huán)體代碼執(zhí)行的次數(shù),在字節(jié)碼中遇到控制流向后跳轉(zhuǎn)的指令稱(chēng)為"回邊"(Back Edge)。顯然,建立回邊計(jì)數(shù)器統(tǒng)計(jì)的目的就是為了觸發(fā)OSR編譯。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容