【Java】 NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException、ArrayIndexOutOfBoundsException、ArrayStoreException、ArithmeticException等没有异常堆栈信息
今天工作中,临时Fix一个bug,一看日志“java.lang.ClassCastException: null”相当懵逼,没有详细堆栈信息,这咋整。虽然根据上下文可以推测代码的大致位置,但不敢拍板确认啊。只好google找一下,在Stackoverflow上果然有解决办法
【解决方法】在java启动命令中添加“-XX:-OmitStackTraceInFastThrow”即可输出详细堆栈信息——亲测可用。
【问题原因】如果同一个错误的日志频繁发生,为了性能优化,同时不至于同样的堆栈日志频繁刷入到日志文件,让日志文件巨增,【CoederBaby】JVM在输出一定次数的异常堆栈后,就会省略堆栈信息
【进一步分析】参看JVM源码(参见附录2),可见这个优化同时试用于以下异常:
- NullPointerException
- ArrayIndexOutOfBoundsException
- ClassCastException
- ArrayIndexOutOfBoundsException
- ArrayStoreException
- ArithmeticException
相关核心代码片段:
// If this throw happens frequently, an uncommon trap might cause // a performance pothole. If there is a local exception handler, // and if this particular bytecode appears to be deoptimizing often, // let us handle the throw inline, with a preconstructed instance. // Note: If the deopt count has blown up, the uncommon trap // runtime is going to flush this nmethod, not matter what. if (treat_throw_as_hot && (!StackTraceInThrowable || OmitStackTraceInFastThrow)) { // If the throw is local, we use a pre-existing instance and // punt on the backtrace. This would lead to a missing backtrace // (a repeat of 4292742) if the backtrace object is ever asked // for its backtrace. // Fixing this remaining case of 4292742 requires some flavor of // escape analysis. Leave that for the future. ciInstance* ex_obj = NULL; switch (reason) { case Deoptimization::Reason_null_check: ex_obj = env()->NullPointerException_instance(); break; case Deoptimization::Reason_div0_check: ex_obj = env()->ArithmeticException_instance(); break; case Deoptimization::Reason_range_check: ex_obj = env()->ArrayIndexOutOfBoundsException_instance(); break; case Deoptimization::Reason_class_check: if (java_bc() == Bytecodes::_aastore) { ex_obj = env()->ArrayStoreException_instance(); } else { ex_obj = env()->ClassCastException_instance(); } break; default: break; }
参考:
- stackoverflow : https://stackoverflow.com/questions/2411487/nullpointerexception-in-java-with-no-stacktrace
- 相关JVM源码:https://hg.openjdk.java.net/jdk/jdk/file/tip/src/hotspot/share/opto/graphKit.cpp