JAVA从入门到精通之JIT中对Exception做的优化
Vivian 2018-07-03 来源 : 阅读 1073 评论 0

摘要:本文主要向大家介绍了JAVA从入门到精通之JIT中对Exception做的优化,通过具体的内容向大家展示,希望对大家在JAVA从入门到精通的路上走的更远。

本文主要向大家介绍了JAVA从入门到精通之JIT中对Exception做的优化,通过具体的内容向大家展示,希望对大家在JAVA从入门到精通的路上走的更远。

今天同事上线上看日志,发现一堆只打印了”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_p0_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即可。

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!

本文由 @Vivian 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程