频道栏目
首页 > 资讯 > Java > 正文

jvm源码之JIT中对Exception做的优化

17-09-25        来源:[db:作者]  
收藏   我要投稿

今天同事上线上看日志,发现一堆只打印了”java.lang.NullPointerException”的异常,代码里面确实捕获且调用了输出堆栈信息的方法,日志里面却没有堆栈信息,甚是困惑。另一个同事说他之前遇到过,好像是JIT优化的结果。代码:

public class NpeThief {
    public void callManyNPEInLoop() {
        for (int i = 0; i < 100000; i++) {
            try {
                ((Object)null).getClass();
            } catch (Exception e) {
                // This will switch from 2 to 0 (indicating our problem is happening)
                System.out.println(e.getStackTrace().length);
            }
        }
    }
    public static void main(String ... args) {
        NpeThief thief = new NpeThief();
        thief.callManyNPEInLoop();
    }
}


以下为启动参数时,在4W+次的时候就开始不打印堆栈信息了:

-Xcomp -server


-Xcomp表示纯编译执行(-Xcomp):所有方法在第一次调用的时候就开始执行编译,会导致启动速度慢。
相对应的是分层编译(-XX:+TieredCompilation): 分别是client启动时的c1编译器和server启动时的c2编译器。这2个编译器的目标不同。c2编译需要大量的统计信息,且编译慢,但是编译完的代码执行效率高。C1编译需要的信息相对少,但是编译快,效率相对低。分层编译就是一个折中,在系统启动的初期,用c1编译以便尽快进入编译执行。然后随着时间执行,大量的统计信息之后,再利用C2编译,以达到性能最大化。

在文章里面看到这样一个参数

-XX:-OmitStackTraceInFastThrow


用该参数作为关键字搜了一下hotspot源码,发现以下这段关键代码:

 if (treat_throw_as_hot
      && (!StackTraceInThrowable || OmitStackTraceInFastThrow)) {
    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(默认值就是true),NullPointerException,ArithmeticException,ArrayIndexOutOfBoundsException,ArrayStoreException,ClassCastException这5种异常在经过JIT优化后都不会输出堆栈信息。主要是空指针异常,除0的异常,数组越界异常,数组存储异常和类型转换异常。

感觉这种情况应该很少见,开启编译模式,都在调用了4W+后才发生。若只是分层编译,在10W+才出现。先记录一下。JIT这块也没有什么深入的理解。要关闭这个也很简单,-XX:-OmitStackTraceInFastThrow即可。

相关TAG标签
上一篇:Adobe AI CC图片批量描摹脚本
下一篇:Rythm.js 使用教程详解
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站