快捷搜索:  as  test

阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层

让我们筹备一个函数:

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

首先我们先容非常表:在编译天生的字节码中,每个措施都附带一个非常表。

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

下图便是我分外指出的JVM字节码中的非常表部分。

我们来阐发一下这几个语句的履行流程,首先履行:

这相称于履行:

再来:

上图相称于履行

有人问:try去哪了?

我顿时就要先容。此时idiv履行完就有非常了,有非常了先找非常表。

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

当法度榜样触发非常时,Java 虚拟时机从上至下遍历非常表中的所有条款。

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

假如匹配,Java 虚拟时机将节制流转移至该条款 target 指针指向的字节码。

我们看 ,是第四个索引指向的字节码出了问题,显然,此时应该匹配红线这一笔记录,从而跳转到第14个索引的字节码。

我们看他怎么做的?

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

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

此时匹配到非常表的条款,跳转到字节码索引23

继承抛出RuntimeExcpetion,可以留意到 这实际上对应了

这个语句,于是我们可以知道,在三个都呈现非常的环境下,实际上终极向外抛出的非常是finally里面的非常。

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

假如遍历完所有非常表条款,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语句的一份复制。

长按下图,扫描二维码,迎接加我的群,一路评论争论问题吧

里面会分享一些资深架构师录制的视频录像:(有Spring,MyBatis,Netty源码阐发,高并发、高机能、散播式、微办事架构的道理,JVM机能优化、散播式架构、口试资料)等这些成为架构师必备的常识体系 进群顿时免费领取!!!

您可能还会对下面的文章感兴趣: