1. 程式人生 > >jvm原始碼閱讀筆記[6]-雜談JIT中對Exception做的優化

jvm原始碼閱讀筆記[6]-雜談JIT中對Exception做的優化

public class NpeThief {
    public void callManyNPEInLoop() {
        for (int i = 0; i < 100000; i++) {
            try {
                ((Object)null).getClass();
            } catch (Exception e) {
                // This will switch from 2 to 0 (indicating our problem is happening)
                System.out.println(e.getStackTrace().length);
            }
        }
    }
    public
static void main(String ... args) { NpeThief thief = new NpeThief(); thief.callManyNPEInLoop(); } }

    
以下為啟動引數時,在4W+次的時候就開始不列印堆疊資訊了:
    

-Xcomp -server

    
    -Xcomp表示純編譯執行(-Xcomp):所有方法在第一次呼叫的時候就開始執行編譯,會導致啟動速度慢。
相對應的是分層編譯(-XX:+TieredCompilation): 分別是client啟動時的c1編譯器和server啟動時的c2編譯器。這2個編譯器的目標不同。c2編譯需要大量的統計資訊,且編譯慢,但是編譯完的程式碼執行效率高。C1編譯需要的資訊相對少,但是編譯快,效率相對低。分層編譯就是一個折中,在系統啟動的初期,用c1編譯以便儘快進入編譯執行。然後隨著時間執行,大量的統計資訊之後,再利用C2編譯,以達到效能最大化。

    在文章裡面看到這樣一個引數

-XX:-OmitStackTraceInFastThrow

    
    用該引數作為關鍵字搜了一下hotspot原始碼,發現以下這段關鍵程式碼:
    

 if (treat_throw_as_hot
      && (!StackTraceInThrowable || OmitStackTraceInFastThrow)) {
    ciInstance* ex_obj = NULL;
    switch (reason) {
    case Deoptimization::Reason_null_check:
      ex_obj = env()->NullPointerException_instance();
      break
; case Deoptimization::Reason_div0_check: ex_obj = env()->ArithmeticException_instance(); break; case Deoptimization::Reason_range_check: ex_obj = env()->ArrayIndexOutOfBoundsException_instance(); break; case Deoptimization::Reason_class_check: if (java_bc() == Bytecodes::_aastore) { ex_obj = env()->ArrayStoreException_instance(); } else { ex_obj = env()->ClassCastException_instance(); } break; }

    
    可以看到,當開啟引數OmitStackTraceInFastThrow(預設值就是true),NullPointerException,ArithmeticException,ArrayIndexOutOfBoundsException,ArrayStoreException,ClassCastException這5種異常在經過JIT優化後都不會輸出堆疊資訊。主要是空指標異常,除0的異常,陣列越界異常,陣列儲存異常和型別轉換異常。
    感覺這種情況應該很少見,開啟編譯模式,都在呼叫了4W+後才發生。若只是分層編譯,在10W+才出現。先記錄一下。JIT這塊也沒有什麼深入的理解。要關閉這個也很簡單,-XX:-OmitStackTraceInFastThrow即可。
    最後附上R大的一篇回答連結
https://www.zhihu.com/question/21405047