JVM 如何“抛出”异常

kar*_*aut 7 java exception jakarta-ee

我知道 JVM 有一个异常表,用于映射可以在给定字节码索引中抛出的可能异常。我还读到 athrow 字节码会抛出堆栈顶部的引用类型异常。我的问题更多地与 irem 等指令如何“抛出”异常有关。

JVM 是否在每条指令执行后检查栈顶以检查是否有异常?非常感谢您对引擎盖下正在发生的任何见解。

mer*_*ike 5

irem 是“逻辑整数余数”运算符。Java 虚拟机规范写道

运行时异常

如果int余数运算符的除数值为 0,则irem抛出ArithmeticException

未指定 JVM 实现如何完成。它可以指示 CPU 在执行除法之前将除数与 0 进行比较,或者执行除法,然后对所讨论的 CPU 发出除以 0 的信号作出反应。由于除以零可能很少见,后一种策略可能更有效。

例如,Intel 64 和 IA-32 架构软件开发人员手册组合卷 3A、3B 和 3C:系统编程指南写道:

6.1 中断和异常概述

当处理器在执行指令时检测到错误条件时会发生异常,例如被零除。处理器检测各种错误情况,包括保护违规、页面错误和内部机器错误。Pentium 4、Intel Xeon、P6 系列和 Pentium 处理器的机器检查架构还允许在检测到内部硬件错误和总线错误时生成机器检查异常。

当接收到中断或检测到异常时,当前运行的程序或任务被挂起,而处理器执行中断或异常处理程序。当处理程序的执行完成时,处理器恢复执行被中断的过程或任务。被中断的过程或任务的恢复不会失去程序的连续性,除非不可能从异常中恢复或中断导致当前正在运行的程序被终止。

因此,JVM 将定义该异常处理程序以创建一个异常对象,在众所周知的寄存器中留下对它的引用,然后继续执行 athrow 字节码指令。