JVM參數OmitStackTraceInFastThrow:不打印NullPointerException異常堆棧


查看線上日志,遇到一個詭異的問題,就是系統大量空指針的異常,但是沒有打印堆棧,導致不方便定位問題。
經過一番代碼調試,確定並非程序代碼問題。沒有線索之后,從Google找到了答案:是因為在server模式下運行的時候,有一個默認選項是-XX:+OmitStackTraceInFastThrow,這個玩意的意思就是當大量拋出同樣的異常的后,后面的異常輸出將不打印堆棧,打印堆棧的時候底層會調用到Throwable.getOurStackTrace()方法,而這個方法是synchronized的,對性能有比較明顯對影響。所以這個參數是合理的。正常情況下,如果打印了幾萬條異常堆棧是很容易發現問題的。但是我們的系統正好趕上訪問量高峰,一不留神就錯過打印詳細堆棧的階段了。

復現測試代碼:

public class NullPointExceptionTest {
    static final Logger logger = LoggerFactory.getLogger(NullPointExceptionTest.class);
    public static void main(String[] args) {
        String test = null;
        int i = 0;
        while (true) {
            try {
                test.length();
            } catch (Exception e) {
                System.out.println(i++ + " - " + e.getStackTrace().length);
                if (e.getStackTrace().length == 0) {
                    logger.error("e is", e);
                    break;
                }
            }
        }
    }
}

知道原因后,那我們的解決辦法可以有:

  1. 歷史數據還在的話,下載歷史數據查看;
  2. 重新啟動服務器,再觀察日志;
  3. 設置JVM參數,暫時禁止掉這個優化選項:-XX:+OmitStackTraceInFastThrow。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM