NullPointerException 沒有打印異常棧問題追蹤


今天去服務器后台看日志,發現有很多NullPointerException異常。我下意識的去找異常棧信息,想看下到底是哪行代碼導致了空指針。但是發現日志中只打印出了如下日志:

null
java.lang.NullPointerException: null

我懷疑是不是打印日志的時候沒有將異常棧打印出來,於是又去翻看應用代碼核實。但是發現日志打印的代碼也是正常的。

logger.error(e.getMessage(),e);

這就納悶了,於是又懷疑是不是日志配置有問題。折騰了一番發現這些配置都沒問題。一時沒有了思路,只好去求助萬能的百度。

問題原因

我在網上找到了這么一段描述:

JVM 虛擬機會對異常信息進行優化,當相同異常出現很多次,會認為它是熱點異常,忽略掉異常堆棧信息;通過增加 JVM 參數:-XX:-OmitStackTraceInFastThrow 可解決。

這個描述能很好的解釋我發現的問題。代碼中出現空指針異常的地方是一個定時任務在不停地調用,當這個異常出現次數太多時 JVM 就會將其過濾掉。

為了驗證我的猜想,我去找了下這個服務剛剛啟動時的代碼,發現這個異常棧是正常打出的,這也驗證了自己的猜想,通過異常棧信息也找到了導致空指針異常的代碼。

問題重現

下面是自己寫的一段代碼來顯示這個額問題:

public class NullPointStackMissBug {

    static Logger logger = LoggerFactory.getLogger(NullPointStackMissBug.class);

    public static void main(String[] args) {

        for (int i = 0; i < 100000 ; i++) {
            try{
                System.out.println("Loop:"+(i+1));
                String str = "test";
                if(true){
                    str = null;
                }
                str.toUpperCase();
            }catch (Exception e){
                logger.error(e.getMessage(),e);
            }
        }
    }

}

在JVM啟動參數中增加:-XX:-OmitStackTraceInFastThrow后,異常就能正常輸出。


免責聲明!

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



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