让我们准备一个函数:

 

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

 

首先我们介绍异常表:在编译生成的字节码中,每个方法都附带一个异常表。

异常表中的每一个条目代表一个异常处理器,并且由 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语句的一份复制。

阿里小哥带你玩转JVM:揭秘try-catch-finally在JVM底层都干了些啥?的更多相关文章

  1. MySQL如何创建一个好索引?创建索引的5条建议【宇哥带你玩转MySQL 索引篇(三)】

    MySQL如何创建一个好索引?创建索引的5条建议 过滤效率高的放前面 对于一个多列索引,它的存储顺序是先按第一列进行比较,然后是第二列,第三列...这样.查询时,如果第一列能够排除的越多,那么后面列需 ...

  2. 【祥哥带你玩HoloLens开发】了解如何实现远程主机为HoloLens实时渲染

    今天有一个兄弟在群里讲到他们的项目模型比较大,单用HoloLens运行设备的性能无法满足需要,问道如何将渲染工作交给服务器来做,讲渲染结果传给HoloLens.正好刚刚看官方github的时候发现一个 ...

  3. 【宇哥带你玩转MySQL】索引篇(一)索引揭秘,看他是如何让你的查询性能指数提升的

    场景复现,一个索引提高600倍查询速度? 首先准备一张books表 create table books( id int not null primary key auto_increment, na ...

  4. 为什么MySQL要用B+树?聊聊B+树与硬盘的前世今生【宇哥带你玩转MySQL 索引篇(二)】

    为什么MySQL要用B+树?聊聊B+树与硬盘的前世今生 在上一节,我们聊到数据库为了让我们的查询加速,通过索引方式对数据进行冗余并排序,这样我们在使用时就可以在排好序的数据里进行快速的二分查找,使得查 ...

  5. 一文带你读懂!华为云在ACMUG技术沙龙上都透露了些啥?

    摘要:近日,华为云数据库业务总裁苏光牛在ACMUG中国MySQL用户组主办的 "华为云专场" 技术沙龙中分享了华为云数据库重磅新品GaussDB的核心能力与竞争优势.那么, Gau ...

  6. Java开发不懂Docker,学尽Java也枉然,阿里P8架构师手把手带你玩转Docker实战

    转: Java开发不懂Docker,学尽Java也枉然,阿里P8架构师手把手带你玩转Docker实战 Docker简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一 ...

  7. 老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩、击穿、穿透

    前文回顾 建议前一篇文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 过期策略 Redis 的过期策略都有哪些? 在聊这个问题之前,一定 ...

  8. 带你玩转Visual Studio

    带你玩转Visual Studio 带你新建一个工程 工程目录下各文件的含义 解决方案与工程 在这之前先了解一个概念:解决方案与工程. 解决方案(Solution):一个大型项目的整体的工作环境: 工 ...

  9. 来吧!带你玩转 Excel VBA

    来吧!带你玩转 Excel VBA 从错失良机到艰辛的DOS征程,从坎坷购机自学路到转机起程,从爱好到事业,他从一个完全不懂电脑的人到VBA高级应用者,一切全是自学…… 我是罗刚君,来自四川的一个小县 ...

随机推荐

  1. macOS Catalina Kernel panic 因为意外而重新启动

    0x00 What's Happend? 我的 MacBook Air 在升级到 Catalina 之后,经常在休眠模式重启,随后在桌面上显示"因为意外而重新启动"的信息,以下是跟 ...

  2. SQL Server重建索引与重组索引会更新统计信息吗?

    在SQL Server中重建索引(Rebuild Index)与重组索引(Reorganize Index)会触发统计信息更新吗? 那么我们先来测试.验证一下: 我们以AdventureWorks20 ...

  3. 一个MongoDB索引走偏的案例及探究分析

    接业务需求,有一个MongoDB的简单查询,太耗时了,执行了 70S 左右,严重影响用户的体验.. 查询代码主要如下: db.duoduologmodel.find({"Tags.SN&qu ...

  4. Jmeter脚本录制攻略

    基于Apache JMeter(5.2.1) 首先在TestPlan里添加一个HTTP代理服务武器: 设置端口,在目标控制器里选择线程组. 在Chrome浏览器里设置代理: 点击启动按钮后,在浏览器登 ...

  5. mysql分组报错Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column

    环境:Server version: 5.7.27-0 ubuntu 18.04.1 (Ubuntu) 执行分组语句:select * from pet group by owner;时报错: mys ...

  6. flask的模板引擎jinja入门教程 包含一个通过网络实时传输Video视频流的示例

    本文首发于个人博客https://kezunlin.me/post/1e37a6/,欢迎阅读最新内容! tutorial to use python flask jinja templates and ...

  7. 基于SpringCloud实现Shard-Jdbc的分库分表模式,数据库扩容方案

    本文源码:GitHub·点这里 || GitEE·点这里 一.项目结构 1.工程结构 2.模块命名 shard-common-entity: 公共代码块 shard-open-inte: 开放接口管理 ...

  8. Astyle 一键格式化项目代码

    代码格式化差异问题: 一个团队有多个开发,因开发习惯不同,开发时少添加了空格.换行等. 格式化代码时,一般会将整个文档格式化,代码提交时会发现未知的修改项. Astyle格式化工具 官网下载地址:Ar ...

  9. Selenium(十九):unittest单元测试框架(五) Page Object设计模式

    1. Page Object设计模式 Page Object是Selenium自动化测试项目开发实践的最佳设计模式之一,它主要体现在对界面交互细节的封装,这样可以使测试方案更关注于业务而非界面细节.从 ...

  10. JS 逻辑

    JS 逻辑 Boolean(逻辑)对象用于将非逻辑值转换为逻辑值(true 或者 false). Boolean 对象 您可以将 Boolean 对象理解为一个产生逻辑值的对象包装器. Boolean ...