背景
排查测试环境日志时,发现订单有映射处理异常没有被抓到,但是打印的异常信息居然是空的,没有具体的原因。
异常信息打印不全,只有java.lang.NullPointerException,查询到的日志信息只有这么一点,但是又发现有的其他异常信息是正常的有完整的具体信息
通过查询资料了解到:
JVM默认是启用:-XX:+OmitStackTraceInFastThrow,当打印同样的错误日志到一定次数就会被JVM默认优化掉。
JDK5以后JVM做了一个优化,当同样的错误日志频繁打印,JIT会重新编译抛出没有堆栈的信息异常。该默认是在-server模式下是默认开启的。
复现代码
package com.huice.platform.trade.platform.jd;
public class OmitStackTraceInFastThrowsStudy {
private static String userName;
private static Integer age;
public static void main(String[] args) {
for (int i = 0; i < 700000; i++) {
try {
userName.length();
int j = age;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
刚开始:
最后到一定数量虚拟机就直接吃掉堆栈错误信息,只剩下空指针异常
配置打印全部日志
-XX:-OmitStackTraceInFastThrow
可以看出打印了全部日志
最后查到该问题的解决方法有三种
1、查询历史日志,如果日志量大就很难了
2、重启服务调用对应接口,再查看
3、直接关闭优化,改为:-XX:-OmitStackTraceInFastThrow