美文网首页
JVM是如何处理异常的?

JVM是如何处理异常的?

作者: 蜡笔没了小新_e8c0 | 来源:发表于2019-02-28 09:55 被阅读0次

异常的基本概念

在Java语言规范中,所有异常都是Throwable类或者其子类的实例。Throwable有两大直接子类。第一个是Error,涵盖程序不应捕获的异常。当程序触发Error时,它的执行状态已经无法恢复,需要中止线程甚至是中止虚拟机。第二子类则是Exception,涵盖程序可能需要捕获并且处理的异常。

Exception有一个特使的子类RuntimeException,用来表示“程序虽然无法继续执行,但是还能抢救一下”的情况。例如:数组索引越界。

RuntimeException和Error属于Java里的非检查异常(unchecked exception)。其他异常则属于检查异常(checked exception)。在Java语法中,所有的检查异常都需要程序显式地捕获(catch),或者在方法声明中用throws关键字标注。通常情况下,程序中自定义的异常应为检查异常,以便最大化利用Java编译器的编译时检查。

异常实例的构造十分昂贵。这是由于在构造异常实例时,Java虚拟机便需要生成该异常的栈轨迹(stack trace)。该操作会逐一访问当前线程的Java栈帧,并且记录下各种调试信息,包括栈帧所指向方法的名字,方法所在的类名,文件名,以及在代码中的第几行触发该异常。

当然,在生成栈轨迹时,Java虚拟机会忽略掉异常构造器以及填充栈帧的Java方法,直接从新建异常位置开始算起。此外,Java虚拟机还会忽略标记为不可见的Java方法栈帧。

异常对应的栈轨迹并非throw语句的位置,而是新建异常的位置。

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

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

其中,from指针和to指针标识了该异常处理器所监控的范围,例如try代码块所覆盖的范围。target指针则指向异常处理器的起始位置,例如catch代码块的起始位置。

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

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

针对异常执行路径,Java编译器会生成一个或多个异常表条目,监控整个try-catch代码块,并且捕获所有种类的异常。这些异常表条目的target指针将指向另一份复制的finally代码块。并且,在这个finally代码块的最后,Java编译器会重新抛出所捕获的异常。

可见,一共有三份finally代码块。其中,前两份分别位于try代码块和catch代码块的正常执行路径出口。最后一份则作为异常处理器,监控try代码块以及catch代码块。它将捕获try代码块触发的未被catch代码块捕获的异常,以及catch代码块触发的异常。

有个小问题?如果catch代码块捕获了异常,并且出发了另一个异常,那么finally捕获并且重抛的异常是哪个呢?答案是后者。也就是所原本的异常便会被忽略掉,不易于代码调试。

相关文章

  • 异常机制详解

    目录介绍 1.什么是异常 2.异常2.1 异常的概述和分类【了解】2.2 JVM默认是如何处理异常的【理解】2.3...

  • Java基础笔记总结(12)-异常处理,File类

    JVM默认是如何处理异常的 main函数有两种处理方式: 1、自己处理该异常然后继续运行 2、自己没有针对的处理方...

  • 2020-06-27【异常】

    异常体系 JVM的默认处理方案 异常处理 自定义异常

  • JVM是如何处理异常

    异常处理的靓噶组成要素是抛出异常和捕获异常。这两大要素共同实现程序控制流的非正常转移。 抛出异常可分为显示和隐式两...

  • Java之异常抛出

    异常的使用概述异常及时Java程序在运行的过程中出行的错误 异常分类 JVM是如何处理异常的 main方法遇到这种...

  • JVM是如何处理异常的?

    异常的基本概念 在Java语言规范中,所有异常都是Throwable类或者其子类的实例。Throwable有两大直...

  • Jvm处理异常的方式和try...catch处理异常

    jvm处理异常的方式:如果我们出现异常没有处理,jvm会帮我们处理,并且终止了程序,异常代码后的程序不会被执行. ...

  • jvm如何处理异常

    异常分类 抛出异常 显示 throw手动抛出y异常 隐示 java虚拟机碰到无法继续执行的异常状态,自动抛出异常 ...

  • 06 JVM 是如何处理异常的

    在 JAVA 中,异常处理的方式主要是抛出异常和捕获异常。这两大要素共同实现程序控制流的非正常转移。 抛出异常可以...

  • 关于异常

    参考资料:JVM如何处理异常深入详解 一、Java 异常的概念和分类 所有的异常都派生于Throwable类的一个...

网友评论

      本文标题:JVM是如何处理异常的?

      本文链接:https://www.haomeiwen.com/subject/cnvcuqtx.html