没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
七、结论
前言
不知道从何时起,传出了这么一句话:Java中使用try catch
会严重影响性能。
然而,事实真的如此么?我们对try catch 应该畏之如猛虎么?
一、JVM 异常处理逻辑
Java 程序中显式抛出异常由athrow指令支持,除了通过 throw
主动抛出异常外,JVM规范中还规定了许多运行时异常会在检测到异常状况
时自动抛出(效果等同athrow),
例如除数为0时就会自动抛出异常,以及大名鼎鼎的 NullPointerException
。
还需要注意的是,JVM 中
异常处理的catch语句不再由字节码指令来实现(很早之前通过 jsr和
ret指令来完成,它们在很早之前的版本里就被舍弃了),现在的JVM通过异常
表(Exception table 方法体中能找到其内容)来完成 catch 语句;很多人说try
catch 影响性能可能就是因为认识还停留于上古时代。
1、我们编写如下的类,add 方法中计算 ++x; 并捕获异常。
public class TestClass {
private static int len = 779;
public int add(int x){
try {
//
若 运 行 时 检 测 到
x = 0,
那 么
jvm
会 自 动 抛 出 异 常 ,
(
可 以 理 解 成 由
jvm
自 己 负 责
athrow
指 令 调 用
)
x = 100/x;
} catch (Exception e) {
x = 100;
}
return x;
}
}
2、使用javap 工具查看上述类的编译后的class文件
# 编 译
javac TestClass.java
# 使 用 javap 查 看 add 方 法 被 编 译 后 的 机 器 指 令
javap -verbose TestClass.class
忽略常量池等其他信息,下边贴出add 方法编译后的 机器指令集:
public int add(int);
descriptor: (I)I
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=2
0: bipush 100 //
加 载 参 数
100
2: iload_1 //
将 一 个
int
型 变 量 推 至 栈 顶
3: idiv //
相 除
4: istore_1 //
除 的 结 果 值 压 入 本 地 变 量
5: goto 11 //
跳 转 到 指 令 :
11
8: astore_2 //
将 引 用 类 型 值 压 入 本 地 变 量
9: bipush 100 //
将单字节常量推送栈顶
<
这里与数值
100
有关,可以尝试修改
100
后的编译结果:
i
const
、
bipush
、
ldc>
10: istore_1 //
将
int
类 型 值 压 入 本 地 变 量
11: iload_1 // int
型 变 量 推 栈 顶
12: ireturn //
返 回
//
注意 看
from
和
to
以及
targer
,然 后对 照着 去看 上述 指令
Exception table:
from to target type
0 5 8 Class java/lang/Exception
LineNumberTable:
line 6: 0
line 9: 5
line 7: 8
line 8: 9
line 10: 11
StackMapTable: number_of_entries = 2
frame_type = 72 /* same_locals_1_stack_item */
stack = [ class java/lang/Exception ]
frame_type = 2 /* same */
再来看 Exception table:
from=0, to=5。指令 0~5 对应的就是 try 语句包含的内容,而targer = 8
正好对应 catch 语句块内部操作。
个人理解,from 和 to 相当于划分区间,只要在这个区间内抛出了type
所对应的,“java/lang/Exception” 异常(主动athrow 或者
由jvm运行时检测到异常自动抛出),那么就跳转到target
所代表的第八行。
若执行过程中,没有异常,直接从第5条指令跳转到第11条指令后返回,由此
可见未发生异常时,所谓的性能损耗几乎不存在;
如果硬是要说的话,用了try catch 编译后指令篇幅变长了;goto
语句跳转会耗费性能,当你写个数百行代码的方法的时候,编译出来成百
上千条指令,这时候这句goto的带来的影响显得微乎其微。
如图所示为去掉try catch 后的指令篇幅,几乎等同上述指令的前五条。
综上所述:“Java中使用try catch 会严重影响性能”
是民间说法,它并不成立。如果不信,接着看下面的测试吧。
二、关于JVM的编译优化
剩余24页未读,继续阅读
资源评论
白话机器学习
- 粉丝: 9704
- 资源: 7681
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功