更新時間:2021-08-23 11:52:51 來源:動力節點 瀏覽1998次
登陸服務器進行例行的檢查,發現異常日志文件里有很多nullPointException,只有簡單的異常名稱,卻沒有堆棧信息。沒有異常堆棧,無法定位錯誤,也就不能修改了。
正確的解決方法是增加一個VM Options:-XX:-OmitStackTraceInFastThrow。這個參數的好處如下:
“JVM對一些特定的異常類型做了Fast Throw優化,如果檢測到在代碼里某個位置連續多次拋出同一類型異常的話,C2會決定用Fast Throw方式來拋出異常,而異常Trace即詳細的異常棧信息會被清空。這種異常拋出速度非常快,因為不需要在堆里分配內存,也不需要構造完整的異常棧信息。”
這個參數,支持的異常類型如下:
NullPointerException
ArithmeticException
ArrayIndexOutOfBoundsException
ArrayStoreException
ClassCastException
通過這個方案,開啟輸出空指針錯誤,很快就定位問題,并解決了。
解決問題后,進行了一番的測試和驗證,如下:
問題驗證
在異常出現5000次以上時,才會丟失堆棧信息。在6600多次的時候丟失堆棧信息,但是并不穩定。代碼如下:
public class JavaNPE extends Thread {
private static int count = 0;
@Override
public void run() {
try {
System.out.println("getSimpleName is:"+this.getClass().getSimpleName() + " execute count:" + (++count));
String str = null;
System.out.println(str.length()); } catch (Throwable e) {
e.printStackTrace(); } }}public class TestFastThrow {
public static void main(String[] args) throws InterruptedException {
JavaNPE javaNPE = new JavaNPE();
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < Integer.MAX_VALUE; i++) {
executorService.execute(javaNPE); //防止打出的日志太快
Thread.sleep(2);
}
}
}
這是一個多線程的程序,寫單線程的測試程序,是否可行呢?于是就嘗試了第一版,代碼如下:
public static void main(String args[]) {
for (int i = 0; i < 10000; i++) {
try {
String value = null;
value.substring(0, 100);
} catch (Exception ex) {
ex.printStackTrace(); } } }
但是,很遺憾,這個程序的異常堆棧信息并不會丟失。程序修改如下:
public void method2() {
String value = null;
value.substring(0, 100);
} public static void main(String args[]) {
ExceptionTest exceptionTest = new ExceptionTest(1);
for (int i = 0; i < 10000; i++) {
try {
exceptionTest.method2(); } catch (Exception ex) {
ex.printStackTrace(); } } }
這個程序在第5530~5550次的時候,會丟失異常堆棧信息,是不穩定的。分析上述兩段單線程的測試代碼,第一段因為異常信息沒有到方法的外面,jvm不能追蹤到異常堆棧信息,所以并不會起作用。
以上就是動力節點小編介紹的"異常堆棧丟失的解決方法",希望對大家有幫助,想了解更多可查看Java堆棧。動力節點在線學習教程,針對沒有任何Java基礎的讀者學習,讓你從入門到精通,主要介紹了一些Java基礎的核心知識,讓同學們更好更方便的學習和了解Java編程,感興趣的同學可以關注一下。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習