Java如何处理除零?

每次完成除法时,它是否只是检查除数是否与零不同(即使在JIT编码中)?

我的意思是VM如何设置抛出exception,而不是先前被操作系统杀死?

在Unix环境中,通过SIGFPE将分零signal引导,JVM将安装一个信号处理程序,该信号处理程序捕获SIGFPE ,然后throw一个ArithmeticException 。 如果您对内部感兴趣,请参阅例如man signal

我认为OP所要求的是基于以下事实:除非SIGFPE处理程序到位,否则大多数进程将在接收此信号时采取默认操作,即终止。 因此,例如C程序

  int main (int argc, char** argv) { int n = 5 / 0; } 

…如果它甚至编译,将被默认的SIGFPESIG_DFL动作杀死。 相反,JVM的处理程序发出( catchRuntimeException以便可以以本机看似的方式处理这些exception。

正如其他几个人指出的那样,只是为了完整性,事实上从内核生成的SIGFPE通常是从处理器本身的特殊中断映射的; 因此,“管道”就像

  • CPU错误陷阱中断→内核中断处理程序→ SIGFPE SIG_DFL →进程死亡

要么

  • CPU错误陷阱中断→内核中断处理程序→JVM中的SIGFPE处理程序→用户代码中的RuntimeException ArithmeticException

在非Unix平台上,处理是类似的。

Java像任何其他语言一样处理这种情况。 除以零错误会产生处理器exception,从而触发中断。 操作系统“读取”中断,并在注册处理程序时将其转发给程序。 由于Java注册了一个处理程序,它会收到错误,然后将其转换为沿堆栈向上移动的ArithmeticException

JVM使用C来捕获除以零的分区:

 #include  #include  #include  void fpe_handler(int signum) { printf("signal is %d", signum); printf("JVM throws an ArithmeticException here...\n"); exit (1); } int main() { int a = 5; int b = 0; signal(SIGFPE, fpe_handler); printf("%d\n", a / b); return 0; } 

编译并运行它打印:

 el@apollo:~$ gcc -o catch_sigfpe myc.c el@apollo:~$ ./catch_sigfpe signal is 8 JVM throws an ArithmeticException here... el@apollo:~$ 

操作系统同步引发SIGFPEexception,C程序捕获它,然后java构造并向您提供ArithmeticException并在其自身之后进行清理以停止Java程序。

详细了解此处返回的信号: http : //publib.boulder.ibm.com/infocenter/javasdk/v6r0/index.jsp?topic =%2Fcom.ibm.java.doc.user.aix64.60%2Fuser%2Fsighand html的

OS向进程发送信号。 默认处理程序将停止进程,但您可以为它定义自己的处理程序。 我敢打赌java VM。