在应用程序的开发和维护中,通常需要借助运行日志来监控和定位问题。其中,在日志中打印异常堆栈信息对于定位问题极为重要,因此,作为一名工程师,对打印异常堆栈应该不陌生。笔者在实践中曾遇到一个奇怪的现象: Java 应用运行中,当发生 NullPointerException,ArithmeticException,ArrayStoreException,ClassCastException,ArrayIndexOutOfBoundsException 这几种异常时,异常的堆栈信息有时会莫名其妙地“丢失”。
以 NullPointerException 为例,正常情况下异常堆栈信息如下所示:
java.lang.NullPointerException
at com.exception.test.core.TestNullPointerException.exceptionTest(TestNullPointerException.java:28)
at com.exception.test.core.TestNullPointerException.main(TestNullPointerException.java:15)
基于上述堆栈,工程师可以迅速地定位问题。然而,有时异常的堆栈会“丢失”,仅能打印出异常的名字,如下所示:
java.lang.NullPointerException
如此简略的异常信息对于定位问题几乎没有意义,那么,究竟是什么原因导致这种现象出现的呢?要弄清其中缘由,还得从 Java 语言的编译、执行及优化原理谈起,本场 Chat 将为读者详细解答。本场 Chat 主要内容如下:
现场还原:Java 异常堆栈丢失问题;
Java 语言的执行原理;
JIT 编译原理;
JVM 如何确定热点代码;
Java 8 后时代;
源码解读:Java 异常堆栈丢失的根因
总结