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