环境/版本一览
- 开发工具:Intellij IDEA 2019.3.1
- spring-boot:2.2.2.RELEASE
- JDK: 1.8.0_111
- Maven: 3.2.5
- Lombok:1.18.10
问题描述
最近查看线上的log日志,发现某一个方法抛出了大量的NPE(NullPointException异常),但是当想要查看具体的NPE发生的代码行时,发现没有具体的堆栈信息,只是打印了Exception的类名,所以就无法精确地找到NPE发生的具体代码行
原因
The compiler in the server VM now provides correct stack backtraces for all "cold" built-in exceptions. For performance purposes, when such an exception is thrown a few times, the method may be recompiled. After recompilation, the compiler may choose a faster tactic using preallocated exceptions that do not provide a stack trace. To disable completely the use of preallocated exceptions, use this new flag: -XX:-OmitStackTraceInFastThrow.
翻译如下
现在,服务器VM中的编译器为所有“冷”内置异常提供了正确的堆栈回溯。为了提高性能,当几次抛出此类异常时,可以重新编译该方法。重新编译后,编译器可以使用不提供堆栈跟踪的预分配异常来选择更快的策略。要完全禁用预分配的异常,请使用以下新标志:-XX:-OmitStackTraceInFastThrow。
解决方案
-
第一种解决方案
设置jvm的启动参数来关闭该策略:
-XX:-OmitStackTraceInFastThrow -
第二种解决方案
重新服务器,例如spring-boot项目,直接重启应用服务,重启服务器时JVM被重新启动,这样再遇到同样的Exception时就会打印出来完整的堆栈信息,但是如果后续重复遇到同样的Exception还是无法打印出具体的异常栈信息