tomcat运行时报错,但查看日志时,只能看到一句NPE,却没有相关的异常栈信息。
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
示例代码
public class NullPointerExceptionMissingStack { public static void main(String[] args) { int i = 0; int j = 0; String x = null; while (i++ < 1_000_000) { try { throwNPE(x); } catch (Exception e) { int length = e.getStackTrace().length; e.printStackTrace(); if (length == 0) { j++; if (j > 100) { System.out.println(i); System.out.println(j); return; } } } } } private static void throwNPE(String x) { x.toString(); }} |
异常抛出次数到达一定程度时,这里jvm会进行优化,只保留了固定的错误,却不再保留异常堆栈,打印内容部分如下:
java.lang.NullPointerException at com.example.test.lang.NullPointerExceptionMissingStack.throwNPE(NullPointerExceptionMissingStack.java:63) at com.example.test.lang.NullPointerExceptionMissingStack.main(NullPointerExceptionMissingStack.java:45)java.lang.NullPointerException at com.example.test.lang.NullPointerExceptionMissingStack.throwNPE(NullPointerExceptionMissingStack.java:63) at com.example.test.lang.NullPointerExceptionMissingStack.main(NullPointerExceptionMissingStack.java:45)java.lang.NullPointerException at com.example.test.lang.NullPointerExceptionMissingStack.throwNPE(NullPointerExceptionMissingStack.java:63) at com.example.test.lang.NullPointerExceptionMissingStack.main(NullPointerExceptionMissingStack.java:45)java.lang.NullPointerException at com.example.test.lang.NullPointerExceptionMissingStack.throwNPE(NullPointerExceptionMissingStack.java:63) at com.example.test.lang.NullPointerExceptionMissingStack.main(NullPointerExceptionMissingStack.java:45)java.lang.NullPointerExceptionjava.lang.NullPointerExceptionjava.lang.NullPointerExceptionjava.lang.NullPointerExceptionjava.lang.NullPointerExceptionjava.lang.NullPointerExceptionjava.lang.NullPointerExceptionjava.lang.NullPointerExceptionjava.lang.NullPointerException |
oracle的官方说明
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.
再将之前tomcat的日志往前查找,的确有完整的异常栈信息。