Does it simply check if divisor is different from zero every time there is division done (even in JIT-ed code)?
I mean how VM manages to throw an exception without being previously killed by the OS?
Values like INFINITY and NaN are available for floating-point numbers but not for integers. As a result, dividing an integer by zero will result in an exception. However, for a float or double, Java allows the operation.
Java will not throw an exception if you divide by float zero. It will detect a run-time error only if you divide by integer zero not double zero. If you divide by 0.0, the result will be INFINITY.
The most common causes of runtime errors in Java are: Dividing a number by zero. Accessing an element in an array that is out of range. Attempting to store an incompatible type value to a collection.
So, when something is divided by zero, mathematicians simply state that the answer is 'undefined'. This is not a totally abstract idea as you can see it in action in the real world. Computer programmers who accidentally divide by zero will get their code stuck in an infinite loop, for instance.
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
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
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.
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
SIG_DFL
→ process deathor
SIGFPE
handler in JVM → RuntimeException
ArithmeticException
in user codeOn non-Unix platforms the handling is analogous.
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.
The JVM catches the Division by Zero like this with 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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With