簡體   English   中英

如何確定Hotspot JVM決定再次重新編譯JIT:ed代碼的原因?

[英]How can I determine why the Hotspot JVM decided to re-compile already JIT:ed code a second time?

我正在嘗試為延遲敏感的Java應用程序編寫一個預熱例程,以便優化前幾個可能因動態類加載和JIT(主要)而減慢的事務。

我面臨的問題是,即使我的預熱代碼加載所有類並通過多次調用它們(至少100次-XX:CompileThreshold)來練習它們,之后當實際用戶登錄這些相同的函數時仍然標記為“非參賽者“並再次重新編譯,這會造成延遲。

JVM標志如下(我只添加了-XX:+ PrintCompilation -verbose:class tp troubleshoot,其他是遺留的):

-Xms5g -Xmx5g -server -XX:+ AggressiveHeap -XX:+ UseFastAccessorMethods -XX:+ PrintGCDetails -XX:CompileThreshold = 100 -XX:-CITime -XX:-PrintGC -XX:-PrintGCTimeStamps -XX:+ PrintCompilation -verbose:類

#Warmup happens here
  12893 2351       my.test.application.hotSpot (355 bytes)
#Real user logs on here
 149755 2351      made not entrant  my.test.application.hotSpot (355 bytes)
 151913 2837       my.test.application.hotSpot (355 bytes)
 152079 2351      made zombie  my.test.application.hotSpot (355 bytes)

在預熱之后沒有發生類加載(我之前可以看到類加載,因此標志正在工作)。

看起來該函數獲得了一個新的ID(2351 vs 2837),這意味着它被JVM視為“不同”。

我如何確定JVM決定重新編譯此函數的原因?

我想這歸結為我如何確定ID改變的原因? 標准是什么?

我嘗試盡可能多地標記盡可能多的方法和類,但無濟於事。

這是JRE 1.6.0_45-b06。

有關如何排除故障或獲取更多信息的任何提示! :)

對於后代,一旦我閱讀了熱點JVM的一些源代碼,它就相當簡單了。

以下標志將指出導致函數被去優化和重新編譯的確切源代碼行:

-XX:+TraceDeoptimization -XX:+WizardMode -XX:+PrintNativeNMethods -XX:+PrintDependencies -XX:+DebugDeoptimization -XX:+LogEvents

通常這是一個if語句。

void function (Object object){
    if ( object == null ){
        // do some uncommon cleanup or initialization
    }
    do_stuff();
}

假設我的熱身代碼從未觸發過if語句。

我假設整個函數將一次編譯,但是,當JIT C2編譯器實際上決定為此函數生成本機代碼時,它不會為if語句生成任何代碼,因為該代碼路徑從未被編譯過拍攝。

它只會生成一個條件分支,在C2編譯器線程中生成陷阱和異常處理程序。 我認為這是因為本機代碼緩存非常小,因此JVM編寫器不希望用可能無用的代碼填充它。

無論如何,如果該語句永遠為真(即對象永遠為空),則該函數將立即無條件地觸發此異常處理並重新編譯(導致凍結/延遲命中大約幾毫秒)。

當然,我的熱身代碼不會以與生產完全相同的方式調用每個函數,我冒昧地猜測,在任何復雜的產品中,這幾乎是不可能的,而且無論如何都是維護噩夢。

這意味着為了有效地預熱java應用程序,代碼中的每個if語句都需要通過預熱代碼調用。

所以我們只是放棄了“熱身”我們的java代碼的想法,因為它並不像有些人想象的那么簡單。

由於以下原因,我們將重新編寫部分應用程序,以支持每次運行數周/數月:

  • 維護更簡單(我們不需要在預熱期間模擬生產並保持更新)
  • JIT不會根據我們的塑料模擬來完成,而是根據生產行為(即使用JIT來實現它的設計而非對抗它)

長期來說,客戶可能需要為C / C ++等重寫付費,以獲得始終如一的低延遲,但這是另一天。

編輯:讓我只是添加更新到熱點JVM的新版本或圍繞熱點JVM參數“調整”永遠不會解決此問題。 它們都是煙霧和鏡子。 事實是熱點JVM從來沒有為可預測的低延遲編寫,這個缺點是不可能在java用戶區內解決的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM