您的位置 首页 php

try-catch异常机性能深度解析

ca5003214b984698b9e01905636c003a

一:概述

在日常 Code 编码中,通常使用处理异常机制来保证程序运行的有效性,也经常听到老码农的异常要谨慎使用的声音,那么该怎么用才正确呢,会不会像有些人说有性能影响呢?更多信息请关注微信公众号: 白白家族


二:实战分析

对于种种疑问,最好的解决方式是刨根问底,一探究竟。

2.1 code案例分析

以下代码是最常见的异常应用,我们以此为起点,逐步探索

public static void main(String[] args) { int a = 1; try { a = 2; return; } catch (RuntimeException e1) { a = 3; } catch (Exception e2) { a = 4; } finanlly { a = 0; } } 

2.2 案例源码分析

想知道上述案例代码做了哪些事情?那我们需要 反编译 上述源文件,从 字节码 执行过程来分析。(为形象展示给各大读者,这里屏蔽晦涩的编码指令,采用伪字节指令码来展示执行过程)

public static voidmain(java.lang.String[]);

Code:

0: 准备工作, 操作a = 1

1: try块开始

2: 操作 a = 2

3: finally块开始!

4: 操作a=0

5: 函数执行完毕,操作 return

6: RuntimeException 异常处理块开始!

7: 操作 a = 3

8: finally处理块

9: 操作a = 0

10: RuntimeException 异常处理块结束, 操作 return

11: Exception e2异常处理块开始!

12: 操作 a = 4

13: finally处理块

14: 操作 a = 0;

15: Exception e2 异常处理块结束, 操作 return

Exception table: // 异常表

from to target type

1 2 6 RuntimeException

1 2 11 Exception

以上流程也不难懂,我们先从了解上述关键字说起:

1) code: 代表指令顺序,表示程序运行的前后顺序,按照序号从小到大以此执行,例如:1执行完就会执行2

2) exception table:异常表,这张表中的每个行记录,记录着代码中定义的异常信息。

其中每一行记录有4个字段信息:

from : 异常的开始 地址

to: 异常的结束地址,

target: 异常的处理起始位

type: 异常类名称

拿第一行 1 2 6 RuntimeException 举例说明,代码执行在1-2中,如遇到RuntimeException 异常,则从指令6开始运行

2.3 追溯上述指令码执行过程

1> 如果异常没有发生,指令码依次运行code=1,2,3,4,5;其中不会运行 6到10 和11到15(如上示例), 也就不会查exception table表,所以如果没有发生异常,写不写try catch对性能是没有消耗的。

2> 当代码抛出了异常时,首先拿着抛出位置到exception table表中查找对应的开始/结束地址,然后匹配出target位置,进行异常处理(如示例注释)。这一步操作在内存查找处理中,是不会影响性能的。


三,经验总结:

但是在实际编码时,我们常常被要求尽量减少try-catch语句块,这是为什么呢?

原因是创建异常对象的代价是非常大的。当程序抛出异常后,它会创建一个异常对象(如案例中的e1、e2对象),收集堆栈异常信息(也就是e.printStackTrace()中展示的信息),并从当前环境中弹出对异常对象的引用,将这些信息反馈给我们。

综上所述,在使用try-catch异常机制时,一方面需要考虑业务层面的必要性,另一方面考虑代码层面异常是否有必要被创建以及被抛出的频率上,根据实际需求,适当地使用try-catch。

更多信息请关注微信公众号: 白白家族

文章来源:智云一二三科技

文章标题:try-catch异常机性能深度解析

文章地址:https://www.zhihuclub.com/31038.shtml

关于作者: 智云科技

热门文章

网站地图