Java 如何处理除以零?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21269461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does Java handle division by zero?
提问by mrpyo
Does it simply check if divisor is different from zero every time there is division done (even in JIT-ed code)?
它是否只是在每次完成除法时检查除数是否不同于零(即使在 JIT 代码中)?
I mean how VM manages to throw an exception without being previously killed by the OS?
我的意思是 VM 如何在没有被操作系统杀死的情况下设法抛出异常?
采纳答案by BRPocock
In an Unix environment, in which division-by-zero is signal
led via SIGFPE
, the JVM will have installed a signal handler which traps the SIGFPE
and in turn throw
s an ArithmeticException
. If you're interested in the internals, see e.g. man signal
在一个Unix环境,在这种划分被零是signal
通过主导SIGFPE
,JVM将已安装的陷阱的信号处理程序SIGFPE
,进而throw
S上的ArithmeticException
。如果您对内部结构感兴趣,请参见例如man signal
What I believe the OP is asking is based on the fact that, until/unless a SIGFPE
handler is in place, most processes will take the default action on receiving this signal, which is to terminate. Thus, e.g. a C program
我相信 OP 的要求是基于这样一个事实:直到/除非SIGFPE
处理程序到位,大多数进程将在接收到此信号时采取默认操作,即终止。因此,例如一个 C 程序
int main (int argc, char** argv) { int n = 5 / 0; }
… if it even compiles, will be killed by the default SIGFPE
→ SIG_DFL
action. The JVM's handler instead issues the (catch
able) RuntimeException
so that these exceptions can be handled in a native-seeming way.
...如果它甚至编译,将被默认的SIGFPE
→SIG_DFL
操作杀死。JVM 的处理程序改为发出 ( catch
able),RuntimeException
以便可以以本机方式处理这些异常。
As several others pointed out, and just for completeness, in point of fact the SIGFPE
generated from the kernel is generally mapped from a special interrupt from the processor itself; thus, the “pipeline” is something like
正如其他几个人指出的那样,为了完整起见,实际上SIGFPE
从内核生成的通常是从处理器本身的特殊中断映射的;因此,“管道”就像
- CPU error trap interrupt → kernel interrupt handler →
SIGFPE
SIG_DFL
→ process death
- CPU 错误陷阱中断 → 内核中断处理程序 →
SIGFPE
SIG_DFL
→ 进程死亡
or
或者
- CPU error trap interrupt → kernel interrupt handler →
SIGFPE
handler in JVM →RuntimeException
ArithmeticException
in user code
- CPU 错误陷阱中断 → 内核中断处理程序 →
SIGFPE
JVM 中的处理程序 →RuntimeException
ArithmeticException
用户代码中
On non-Unix platforms the handling is analogous.
在非 Unix 平台上,处理是类似的。
回答by Micha? ?rajer
OS sends signal to the process. Default handler would stop the process, but you can define own handler for it. I bet java VM does.
操作系统向进程发送信号。默认处理程序将停止进程,但您可以为其定义自己的处理程序。我敢打赌 java VM 确实如此。
回答by 64BitBob
Java handles the situation like any other language. A divide by zero error generates a processor exception which triggers an interrupt. The interrupt is "read" by the operating system and forwarded to the program if a handler is registered. Since Java registers a handler, it receives the error and then translates it into an ArithmeticException
that travels up the stack.
Java 像处理任何其他语言一样处理这种情况。除以零错误会生成触发中断的处理器异常。如果注册了处理程序,则中断由操作系统“读取”并转发给程序。由于 Java 注册了一个处理程序,它会接收到错误,然后将其转换为ArithmeticException
向上传输的 。
回答by Eric Leschinski
The JVM catches the Division by Zero like this with C:
JVM 像这样用 C 捕获除以零:
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
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;
}
Compile and run it prints this:
编译并运行它会打印:
el@apollo:~$ gcc -o catch_sigfpe myc.c
el@apollo:~$ ./catch_sigfpe
signal is 8
JVM throws an ArithmeticException here...
el@apollo:~$
The operating system synchronously raises a SIGFPE exception, the C program catches it, and then the java constructs and feeds you the ArithmeticException and cleans up after itself to stop the Java program.
操作系统同步引发 SIGFPE 异常,C 程序捕获它,然后 java 构造并提供给您 ArithmeticException 并自行清理以停止 Java 程序。
See more about the signal returned here: http://publib.boulder.ibm.com/infocenter/javasdk/v6r0/index.jsp?topic=%2Fcom.ibm.java.doc.user.aix64.60%2Fuser%2Fsighand.html
查看有关此处返回的信号的更多信息:http: //publib.boulder.ibm.com/infocenter/javasdk/v6r0/index.jsp?topic=%2Fcom.ibm.java.doc.user.aix64.60%2Fuser%2Fsighand .html