我只是好奇Java JVM有时如何内联可能抛出异常的方法。我假设至少可以内联一些这样的方法(例如那些具有数组访问权限并因此可能抛出的方法) ArrayIndexOutOfBoundsException
S)。我看到的问题是,如果实际发生异常,如果您已经内联方法,如何显示正确的堆栈跟踪?由于可以在不同的机器上内联不同的方法,内联如何不破坏堆栈跟踪机制?
我只是好奇Java JVM有时如何内联可能抛出异常的方法。我假设至少可以内联一些这样的方法(例如那些具有数组访问权限并因此可能抛出的方法) ArrayIndexOutOfBoundsException
S)。我看到的问题是,如果实际发生异常,如果您已经内联方法,如何显示正确的堆栈跟踪?由于可以在不同的机器上内联不同的方法,内联如何不破坏堆栈跟踪机制?
你设想的问题是什么?由于它是JVM本身进行内联,所以没有什么可以阻止它在构造堆栈跟踪以安装在Throwable对象中时记住它内联的位置并对此进行更正。
当有例外时 抛出构建后,JVM将遍历CPU堆栈并确定每个机器堆栈帧是否对应于解释的字节码,JITted代码,来自库的本机代码等等。为此,它指的是表示机器代码中哪些地址对应于字节码中的哪些指令(以及进一步返回源行,如果该类信息存在于类文件中)的表。该表可以很好地指定JITted代码中的某个位置可以对应多个Java级堆栈帧。
但是,JVM不是 需要 去做这个。它也可以简单地选择构造具有神秘中断的堆栈轨迹。见 用于Throwable.getStackTrace()的javadoc。 (甚至不要求JVM能够产生堆栈跟踪 一点都不)。
你可能想看看 这个文件 这解释了异常处理在JVM中的工作原理:
每种方法都可以 捕获异常与异常表相关联 在类文件中传递的字节码序列 方法。异常表为每个异常都有一个条目 被每个尝试块捕获。每个条目有四条信息: 起点和终点,字节码序列中的pc偏移量 跳转到,以及异常类的常量池索引 被抓住了