更新時(shí)間:2021-08-23 11:52:51 來源:動(dòng)力節(jié)點(diǎn) 瀏覽2288次
登陸服務(wù)器進(jìn)行例行的檢查,發(fā)現(xiàn)異常日志文件里有很多nullPointException,只有簡單的異常名稱,卻沒有堆棧信息。沒有異常堆棧,無法定位錯(cuò)誤,也就不能修改了。
正確的解決方法是增加一個(gè)VM Options:-XX:-OmitStackTraceInFastThrow。這個(gè)參數(shù)的好處如下:
“JVM對(duì)一些特定的異常類型做了Fast Throw優(yōu)化,如果檢測(cè)到在代碼里某個(gè)位置連續(xù)多次拋出同一類型異常的話,C2會(huì)決定用Fast Throw方式來拋出異常,而異常Trace即詳細(xì)的異常棧信息會(huì)被清空。這種異常拋出速度非常快,因?yàn)椴恍枰诙牙锓峙鋬?nèi)存,也不需要構(gòu)造完整的異常棧信息。”
這個(gè)參數(shù),支持的異常類型如下:
NullPointerException
ArithmeticException
ArrayIndexOutOfBoundsException
ArrayStoreException
ClassCastException
通過這個(gè)方案,開啟輸出空指針錯(cuò)誤,很快就定位問題,并解決了。
解決問題后,進(jìn)行了一番的測(cè)試和驗(yàn)證,如下:
問題驗(yàn)證
在異常出現(xiàn)5000次以上時(shí),才會(huì)丟失堆棧信息。在6600多次的時(shí)候丟失堆棧信息,但是并不穩(wěn)定。代碼如下:
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);
}
}
}
這是一個(gè)多線程的程序,寫單線程的測(cè)試程序,是否可行呢?于是就嘗試了第一版,代碼如下:
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(); } } }
但是,很遺憾,這個(gè)程序的異常堆棧信息并不會(huì)丟失。程序修改如下:
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(); } } }
這個(gè)程序在第5530~5550次的時(shí)候,會(huì)丟失異常堆棧信息,是不穩(wěn)定的。分析上述兩段單線程的測(cè)試代碼,第一段因?yàn)楫惓P畔]有到方法的外面,jvm不能追蹤到異常堆棧信息,所以并不會(huì)起作用。
以上就是動(dòng)力節(jié)點(diǎn)小編介紹的"異常堆棧丟失的解決方法",希望對(duì)大家有幫助,想了解更多可查看Java堆棧。動(dòng)力節(jié)點(diǎn)在線學(xué)習(xí)教程,針對(duì)沒有任何Java基礎(chǔ)的讀者學(xué)習(xí),讓你從入門到精通,主要介紹了一些Java基礎(chǔ)的核心知識(shí),讓同學(xué)們更好更方便的學(xué)習(xí)和了解Java編程,感興趣的同學(xué)可以關(guān)注一下。
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)