一、现象
实时作业中使用:
try{...}
catch(RuntimeException e) {
log.error("Get exception: {}", e);
}
日志只输出:
Get exception: java.lang.NullPointerException
并没有对应的异常栈信息。
二、原因
HotSpot JVM有个优化:有些特定的隐式异常类型(NullPointerException、ArithmeticException( / 0)之类)如果在代码里某个特定位置被抛出过多次的话,JVM会直接抛出一个事先分配好的、类型匹配的异常对象。这个对象的message和stack trace都被清空。抛出这个异常的速度是非常快,不但不用额外分配内存,而且也不用爬栈;但反面就是可能正好是需要知道哪里出问题的时候看不到stack trace了。
三、解决
JVM提供了-XX:-OmitStackTraceInFastThrow这个虚拟机参数来告诉JIT编译器禁用这种异常的优化。