【05】JVM是如何处理异常的

一、异常的概念

所有异常都是Throwable类或者其子类的实例。

Throwable有两大直接子类,第一个是ERROR,涵盖程序不应捕获的异常,当程序触发Error时,其执行状态已经无法恢复,需要中止线程甚至是终止虚拟机;第二个是Exception,涵盖程序可能需要捕获并且处理的异常。

捕获异常涉及三种代码块

(1)try代码块:用来标记需要进行异常监控的代码

(2)catch代码块:跟在try代码块之后,用来捕获在try代码块中触发的某种特定类型的异常。Java虚拟机会从上而下匹配异常处理器,因此,前面的catch代码块所捕获的异常类型不能覆盖后边的,否则编译器会报错

(3)finally代码块:跟在try代码块和catch代码块之后,用来声明一段必定运行的代码。它的设计初衷是为了避免跳过某些关键的清理代码,例如关闭已经打开的系统资源。

二、Java虚拟机是如何捕获异常的

在编译生成的字节码中,每个方法都附带一个异常表。异常表中的每个条目代表一个异常处理器,由from指针、to指针、target指针及其所捕获的异常类型构成。这些指针的值是字节码索引,用以定位字节码。

java 复制代码
public static void main(String[] args) {
  try {
    mayThrowException();
  } catch (Exception e) {
    e.printStackTrace();
  }
}
// 对应的 Java 字节码
public static void main(java.lang.String[]);
  Code:
    0: invokestatic mayThrowException:()V
    3: goto 11
    6: astore_1
    7: aload_1
    8: invokevirtual java.lang.Exception.printStackTrace
   11: return
// 编译后,该方法异常表拥有如下一个条目
  Exception table:
    from  to target type
      0   3   6  Class java/lang/Exception  // 异常表条目
      
// from 为0 to 为 3代表它的监控范围从索引为0的字节码开始,到索引为3的字节码结束(不包括3)
// target为6代表该索引处理器从索引为6的字节码开始。
//type 代表异常处理器捕获的异常类型是Exception

当程序触发异常时,Java虚拟机会遍历异常表中的所有条目。当触发异常的字节码的索引值在异常条目的监控范围内,JVM会判断所抛出的异常和该条目想要捕获的异常是否匹配。若匹配,JVM会将控制流转移至该条目target指针指向的字节码。

若遍历完所有异常表条目,JVM仍未匹配到异常处理器,则会弹出对应的Java栈帧,并且在调用者中重复上述操作。

思考:

1:使用异常捕获的代码为什么比较耗费性能?

因为构造异常的实例比较耗性能。这从代码层面很难理解,不过站在JVM的角度来看就简单了,因为JVM在构造异常实例时需要生成该异常的栈轨迹。这个操作会逐一访问当前线程的栈帧,并且记录下各种调试信息,包括栈帧所指向方法的名字,方法所在的类名、文件名,以及在代码中的第几行触发该异常等信息。

虽然具体不清楚JVM的实现细节,但是看描述这件事情也是比较费时费力的。

2:finally是怎么实现无论异常与否都能被执行的?

这个事情是由编译器来实现的,现在的做法是这样的,编译器在编译Java代码时,会复制finally代码块的内容,然后分别放在try-catch代码块所有的正常执行路径及异常执行路径的出口中。

相关推荐
wuminyu34 分钟前
JVM规范学习总结-JVM规范基本概念
java·linux·c语言·jvm·c++
学到老活到老15 小时前
方法执行完了,对象为什么还占着内存?
java·jvm
骑着蜗牛撵大象3271 天前
四种库收进一个SQL编辑器(下):跨库取数、方言对齐与四库巡检的落地拆解
jvm·数据库·sql·编辑器·数据迁移·跨库查询
需要8262 天前
容器化 Java:镜像瘦身与 JVM 容器感知(cgroup)
java·开发语言·jvm
Pniubi2 天前
ConcurrentHashMap拆分线程池难点再讲
java·jvm
Irene19913 天前
Flink 学习日志 01:前端转大数据的实战避坑指南
java·jvm·flink
小天源4 天前
从 Nginx 日志到访问分析:轻量化网站监测服务的架构实践
jvm·nginx·网络安全·架构·网络监控
十年Java程序媛4 天前
JVM 内存区域与对象内存布局|new 对象底层流程,对象头 MarkWord 详解
java·jvm·spring boot
用户094248568034 天前
第2章:Windows、WSL2 与 Docker 环境搭建Redis
java·jvm
梅梅绵绵冰4 天前
JVM虚拟机
java·开发语言·jvm