消除Java应用中的Exception开销

抛异常最大的消耗在于构造整个异常栈的过程,如果你的栈很深,特别是用了一些框架的话,这个开销基本是不可忽视的,之前做的一个优化显示当时应用中的一个异常使得整个应用的性能下降至少30%。

一、开销在哪

最大开销的地方在这里,当你去new一个Exception的时候,会调用父类Throwable的构造函数,Throwable的构造函数中会调用native的fillInStackTrace(),这个方法就会构造整个异常栈了

二、优化方案

        JAVA语言中提供了try/catch来开发方便用户捕捉异常,进行异常的处理。但是如果使用不当,也会给JAvA程序的性能带来影响。因此,要注意以下儿点。慎用异常,异常对性能不利。抛出异常首先要创建一个新的对象。Throwable接口的构造函数调用名为fillInStackTrace()的本地(Native)方法filllnStackTrace()方法检查堆栈,收集调用跟踪信息。只要有异常被抛出,VM就必须调整调用堆栈。

1、避免使用异常来控制程序流程

        如果可以用if、while等逻辑语句来处理,那么就尽可能的不用try/catch语句。抛出异常首先要创建一个新的对象。Throwable 接口的构造函数调用名为 fillInStackTrace()的本地方法,fillInStackTrace()方法检查栈,收集调用跟踪信息。只要有异常被抛出,VM 就必须调整调用栈,因为在处理过程中创建了一个新的对象。  异常只能用于错误处理,不应该用来控制程序流程。  

2、尽可能重用异常

        在必须要进行异常的处理时,要尽可能的重用已经存在的异常对象。因为在异常的处理中,生成个异常对象要消耗掉大部分的时间。

3、将try/catch 块移出循环  

 
        把try/catch块放入循环体内,会极大的影响性能,如果编译 jit 被关闭或者你所使用的是一个不带 jit 的jvm,性能会将下降21%之多!  

三、寻找异常

有时候你可能无法直接找到到底哪个异常抛得最多,最典型的是引入了一个三方包,它里面自己抛了异常然后又自己catch住了,外面压根不知道里面居然还有这些破事儿。

可以用perf top去看下us的开销,如果_ZN19java_lang_Throwable19fill_in_stack_traceE6HandleP6Thread这个排名很靠前,那就有必要看看异常的大头在哪里。

最简单的用BTrace去跟一下Exception.<init>看构造Exception的栈是什么样的,然后排序汇总一下,一般就能看到什么Excetion最多,是谁抛的,然后有针对性地把它们去掉或者优化掉。

然后再压测你的应用,对CPU的开销会减少不少。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值