文章目录

  • ​​场景​​
  • ​​解决方案​​
  • ​​在idea中试验​​

场景

生产环境抛异常,但不打印堆栈信息,只简单的提示java.lang.NullPointerException。

先看代码对不对:

try{
String s=null;
s.indexOf(4);
} catch (Exception e){
logger.error("exception:{}",e);
}

代码是没问题的,因为本地调试可以打印堆栈信息,但在服务器上只提示空指针异常。

解决方案

问题原因:
JVM在默认启动的时候会加上OmitStackTraceInFastThrow参数,含义是当大量抛出同样的异常的后,后面的异常输出将不打印堆栈。原因是打印堆栈的时候底层会调用到Throwable.getOurStackTrace()方法,而这个方法是synchronized的,对性能有比较明显的影响。所以这个参数设置是合理的。

OmitStackTraceInFastThrow 表示 快速抛异常时是否忽略堆栈。
+表示是
-表示否

-XX:+OmitStackTraceInFastThrow
服务器默认(+),忽略堆栈,不打印。


-XX:-OmitStackTraceInFastThrow
如果要打印,设置为(-),不忽略堆栈,打印。

利弊自己权衡吧,不忽略堆栈性能高一些(服务器默认)。
忽略堆栈不好定位问题。

在idea中试验

代码:

@ResponseBody
@RequestMapping("/makeError")
public String makeError(){
Double d =null;
for (int i = 0; i < 10000; i++) {
try {
new BigDecimal(d);
}catch(Exception e){
logger.error("makeError系统异常!原因:", e);
}
}

return "success";
}

jvm参数设置:
-server
-XX:+OmitStackTraceInFastThrow

发现打印了几万行,还是有堆栈,这是为什么呢?