阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?

栏目: Java · 发布时间: 5年前

内容简介:每日早8点半,精品技术文章准时送上

点击上方 石杉的架构笔记 ,右上选择“ 设为星标

每日早8点半,精品技术文章准时送上

往期文章

BAT 面试官是如何360°无死角考察候选人的(上篇)

每秒上万并发下的Spring Cloud参数优化实战

分布式事务如何保障实际生产中99.99%高可用

记一位朋友斩获 BAT 技术专家Offer的面试经历

亿级流量架构系列之如何支撑百亿级数据的存储与计算

作者:李瑞杰

目前就职于阿里巴巴,狂热JVM爱好者

让我们准备一个函数:


阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?

然后,反编译他的字节码:

阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥? 首先我们介绍异常表:在编译生成的字节码中,每个方法都附带一个异常表。

异常表中的每一个条目代表一个异常处理器,并且由 from 指针、to 指针、target 指针以及所捕获的异常类型构成。这些指针的值是字节码索引用以定位字节码。


下图就是我特别指出的JVM字节码中的异常表部分。

阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥? 我们来分析一下这几个语句的执行流程,首先执行:

阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥? 这相当于执行:

阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?     

再来:

阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?

上图相当于执行

阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?

有人问: try去哪了?

我马上就要介绍。此时idiv执行完就有异常了,有异常了先找异常表。

阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?

我再贴一下异常表, 他是怎么搜索的呢?

当程序触发异常时,Java 虚拟机会从上至下遍历异常表中的所有条目。

当触发异常的字节码的索引值在某个异常表条目的监控范围内,Java 虚拟机会判断所抛出的异常和该条目想要捕获的异常是否匹配。

如果匹配,Java 虚拟机会将控制流转移至该条目 target 指针指向的字节码。

我们看 ,是第四个索引指向的字节码出了问题,显然,此时应该匹配红线这一条记录, 从而跳转到第14个索引的字节码。 阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?

我们看他怎么做的?

阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?

new出一个RuntimeException并抛出,它就是


阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?

这一句,按照我们刚才的流程,此时依然需要找到这个RuntimeException在哪个异常表的条目中


阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?

此时匹配到异常表的条目,跳转到字节码索引23
阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?

继续抛出RuntimeExcpetion,可以注意到 这实际上对应了
阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?

这个语句,于是我们可以知道,在三个都出现异常的情况下,实际上最终向外抛出的异常是finally里面的异常。

可以看到当31索引处调用athrow语句抛出异常时,此时异常表没有任何一个条目能够匹配该异常,此时怎么办呢?

阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?     

如果遍历完所有异常表条目,Java 虚拟机仍未匹配到异常处理器,那么它会弹出当前方法对应的 Java 栈帧,并且在调用者中重复上述操作。

在最坏情况下,Java 虚拟机需要遍历当前线程 Java 栈上所有方法的异常表。

事实上分析以上的整体的全部语句你可以发现, jvm层面有真正的finally吗?

没有

现在的做法是,复制 finally 代码块的内容,分别放在 try-catch 代码块所有正常执行路径以及异常执行路径的出口中。无论是否出现异常,确保一定会执行finally语句。

刚才catch出了异常,依然执行finally语句就可以发现这一点。至于其他路径,大家可以自行验证。我就在这里抛砖引玉了。
   

至于为什么2-6发生任何异常都跳转到23?大家可以自己想一下这个问题。

我就提示一点 2-6 target为14的条目代表的catch是不能捕获所有异常的,但是你要确保finally的语句能够执行。而2-6恰巧是try语句块的内容。23这个索引恰巧是finally语句的一份复制。

END

划至底部,点击“ 在看 ”,是你来过的仪式感!

推荐阅读:

更多文章:

欢迎长按下图关注公众号 石杉的架构笔记

阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?

BAT架构经验倾囊相授

阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

黑客攻防技术宝典(第2版)

黑客攻防技术宝典(第2版)

[英] Dafydd Stuttard、[英] Marcus Pinto / 石华耀、傅志红 / 人民邮电出版社 / 2012-6-26 / 99.00元

内容简介: Web应用无处不在,安全隐患如影随形。承载着丰富功能与用途的Web应用程序中布满了各种漏洞,攻击者能够利用这些漏洞盗取用户资料,实施诈骗,破坏其他系统等。近年来,一些公司的网络系统频频遭受攻击,导致用户信息泄露,造成不良影响。因此,如何确保Web应用程序的安全,已成为摆在人们眼前亟待解决的问题。 本书是Web安全领域专家的经验结晶,系统阐述了如何针对Web应用程序展开攻击与......一起来看看 《黑客攻防技术宝典(第2版)》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换