如何在JVM知道在哪里可以在运行时捕捉异常?(How does the JVM know where

2019-08-02 04:36发布

从我的理解, throw是一颗灵长类动物的JVM命令。 当这个被调用时,JVM“检查当前调用堆栈可以抓住它。” 如果不能,那么Java简单地弹出调用栈几乎完全一样,如果返回被调用。 那么JVM“检查当前调用堆栈可以抓住它”等等递归。

我的问题:它怎么可能算法为JVM知道在哪里调用栈可以赶上一个给定的例外? 有没有的元数据存储在每个调用堆栈入口映射例外代码块? 有没有在某种程度上会自动跟踪堆的静态数据结构? 因为地方必须有数据保持跟踪。

Answer 1:

在JVM规范有这个细节。

特别是, 第4.7.3节提供了有关异常表,这是一系列的条目说这异常哪些指令夹缝中的细节。 第3.12节给出了一个具体的例子。

这个元数据如何映射到本地代码的JIT当然是另当别论, - 和具体实现的。 例如,可能会有一些映射从本地实时编译代码回到原来的位置,字节码指令的每个位置,此时的异常表可以协商,以找到合适的处理程序回来。



Answer 2:

一般来说:当一个异常被抛出的JVM提取“调用栈”。 这标识该字节码或机器指令正在在调用堆栈每个水平执行时,与该位置关联的类和方法一起。

然后,堆栈中的每个方法(从其中异常发生和向后工作方法),JVM长相(在内部类对象)在方法的表映射的try / catch范围成字节码/机器指令范围。

如果一个“匹配”在表中找到一种方法,和被抛出异常的类型正被监视的一类用于在找到的范围内,则控制被转移到catch入口点,异常设置成一种后参数的位置,这样的catch子句可以参考它。

如果表中,然后调用堆栈有效地在try / catch语句的前面方法的表“弹出”,放置在堆栈的顶部的下一个较早的方法,和上面搜索“匹配”未找到“匹配”范围是重复的。

当然这是一个过于简单化。 有很多参与处理额外的逻辑的finally范围,例如,一些“边缘”的情况。



文章来源: How does the JVM know where to catch an exception at runtime?