// 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. // 这里要满足两个条件:1.检测到频繁抛出异常,2. OmitStackTraceInFastThrow为true,或StackTraceInThrowable为false 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; } ... ... }
OmitStackTraceInFastThrow和StackTraceInThrowable都默认为true。所以条件 (!StackTraceInThrowable || OmitStackTraceInFastThrow)为true,即JVM默认开启了Fast Throw优化。通过实测发现在若干次(测试多次,发现每次次数不一样,有可能是JVM内部是一个动态值)以后便不打印堆栈信息。
测试代码如下:
public static void main(String[] args) { String test = null; int i = 0; while (true) { try { test.length(); } catch (Exception e) { System.out.println("次数为:" + i++ + ",堆栈长度为:" + e.getStackTrace().length); //log.error("StackTrace is ",e); if (e.getStackTrace().length == 0) { log.error("no StackTrace is ", e); break; } } } }
1)在idea中添加启动参数,如下图:
2)在生产环境中添加启动参数,如:
local OMIT_STACKTRACE_OPTS="-XX:-OmitStackTraceInFastThrow" nohup $JAVA_HOME/bin/java $OMIT_STACKTRACE_OPTS -jar $JAR_NAME >/dev/null 2>&1 &
JVM只对几个特定类型异常开启了Fast Throw优化,这些异常包括:
NullPointerException
ArithmeticException
ArrayIndexOutOfBoundsException
ArrayStoreException
ClassCastException
强制要求JVM始终抛出含堆栈的异常(-XX:-OmitStackTraceInFastThrow)
原文:https://www.cnblogs.com/share-duke/p/12323576.html