成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

解決 Java 打印日志吞異常堆棧的問題

開發
前幾天有同學找我查一個空指針問題,Java 打印日志時,異常堆棧信息被吞了,導致定位不到出問題的地方。

前幾天有同學找我查一個空指針問題,Java 打印日志時,異常堆棧信息被吞了,導致定位不到出問題的地方。

現象

捕獲異常打印日志的代碼類似這樣:

try {
    // ...
} catch (Exception e) {
    log.error("系統異常 customerCode:{},data:{}", customerCode, data, e);
    // ...
}

查到的日志是這樣的:

2023-06-26 11:11:11.111 ERROR 1 --- [pool-1-thread-1] c.mazhuang.service.impl.TestServiceImpl  : 系統異常 customerCode:123,data:{"name":"mazhuang","age":18}
java.lang.NullPointerException: null

異常堆棧丟了。

分析

在之前的一篇文章里已經驗證過這種寫法是可以正常打印異常和堆棧信息的:AI 自動補全的這句日志能正常打印嗎?

再三確認代碼寫法沒問題,納悶之下只好搜索了一下關鍵詞「Java異常堆棧丟失」,發現了這篇文章:Java異常堆棧丟失的現象及解決方法,這里面提到的問題與我們遇到的一樣,而且給出了 Oracle 官方文檔里的相關說明:

https://www.oracle.com/java/technologies/javase/release-notes-introduction.html

The compiler in the server VM now provides correct stack backtraces for all “cold” built-in exceptions. For performance purposes, when such an exception is thrown a few times, the method may be recompiled. After recompilation, the compiler may choose a faster tactic using preallocated exceptions that do not provide a stack trace. To disable completely the use of preallocated exceptions, use this new flag: -XX:-OmitStackTraceInFastThrow.

大致意思就是說,為了提高性能,JVM 會針對一些內建異常進行優化,在這些異常被某方法多次拋出時,JVM 可能會重編譯該方法,這時候就可能會使用不提供堆棧信息的預分配異常。如果想要完全禁用預分配異常,可以使用 -XX:-OmitStackTraceInFastThrow 參數。

了解到這個信息后,翻了翻從服務上次發版以來的這條日志,果然最早的十幾次打印是有異常堆棧的,后面就沒有了。

解決方案

回溯歷史日志,找到正常打印的堆棧信息,定位和解決問題;

也可以考慮在 JVM 參數里加上 -XX:-OmitStackTraceInFastThrow 參數,禁用優化;

本地復現

在本地寫一個簡單的程序復現一下:

public class StackTraceInFastThrowDemo {
    public static void main(String[] args) {
        int count = 0;
        boolean flag = true;
        while (flag) {
            try {
                count++;
                npeTest(null);
            } catch (Exception e) {
                int stackTraceLength = e.getStackTrace().length;
                System.out.printf("count: %d, stacktrace length: %d%n", count, stackTraceLength);
                if (stackTraceLength == 0) {
                    flag = false;
                }
            }
        }
    }

    public static void npeTest(Integer i) {
        System.out.println(i.toString());
    }
}

不添加 -XX:-OmitStackTraceInFastThrow 作為 JVM 參數時,運行結果如下:

...
count: 5783, stacktrace length: 2
count: 5784, stacktrace length: 2
count: 5785, stacktrace length: 0

Process finished with exit code 0

在我本機一般運行五六千次后,會出現異常堆棧丟失的情況。

添加 -XX:-OmitStackTraceInFastThrow 作為 JVM 參數時,運行結果如下:

...
count: 3146938, stacktrace length: 2
count: 3146939, stacktrace length: 2
count: 3146940, stacktrace length: 
Process finished with exit code 137 (interrupted by signal 9: SIGKILL)

運行了幾百萬次也不會出現異常堆棧丟失的情況,手動終止程序。

完整源碼見:https://github.com/mzlogin/java-notes/blob/master/src/org/mazhuang/StackTraceInFastThrowDemo.java

責任編輯:趙寧寧 來源: 悶騷的程序員
相關推薦

2012-10-15 18:01:39

打印機打印機不能打印

2009-11-09 10:10:13

WCF異常

2010-05-06 18:12:47

Unix系統

2024-05-08 16:44:40

TCPRST網絡協議

2023-03-10 09:11:52

高性能Go堆棧

2010-09-07 14:33:30

DIVmargin

2011-12-21 11:18:59

Java

2010-09-06 10:14:55

2009-06-30 16:03:00

異常Java

2009-03-26 08:30:11

2011-05-06 15:56:38

打印機故障

2011-04-28 15:35:38

打印驅動

2010-10-08 15:35:32

Javascriptimg

2013-02-26 09:51:31

Windows 8應用異常問題

2025-03-06 08:37:01

2010-09-30 15:10:12

Javascriptimg

2011-04-28 16:30:55

打印機打印問題

2011-03-10 14:28:45

Access2007日期大寫

2010-04-29 15:46:47

Unix操作系統

2015-10-28 15:20:13

oracle歸檔日志ORA-00257
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91中文在线观看 | 成人免费视频在线观看 | 99精品久久久久 | 久久久人成影片免费观看 | 中文字幕欧美一区 | 亚洲精品视频一区 | 久久久久久久久久久高潮一区二区 | 91精品国产综合久久婷婷香蕉 | 青青伊人久久 | 婷婷综合激情 | 国产精品视频在线观看 | 日韩精品三区 | 国产精品久久久久久久久久久久久 | www.色综合| 特级a欧美做爰片毛片 | 欧美精品一区二区三区蜜桃视频 | 欧美三区在线观看 | 午夜影院毛片 | 中文字幕一级毛片视频 | 国产精品成人一区二区三区 | 欧美日本在线观看 | 欧美视频二区 | 无码一区二区三区视频 | 欧美一区二区三区大片 | 久久久久亚洲av毛片大全 | 国产精品2区 | 亚洲精品久久久一区二区三区 | 黄色大片免费播放 | 亚洲一二三在线 | 成人久久18免费网站 | 亚洲国产二区 | 久久久蜜臀国产一区二区 | 成人精品一区二区三区中文字幕 | 国产精品一区在线播放 | 日韩在线播放中文字幕 | 亚洲一区二区av | 天天草夜夜骑 | 激情婷婷 | 欧美一级片a | 欧美日韩精品一区二区三区视频 | 嫩草国产|