Подтвердить что ты не робот

Как Java обрабатывает деление на ноль?

Проверяет, не отличается ли дивизор от нуля каждый раз, когда выполняется разделение (даже в JIT-ed-коде)?

Я имею в виду, как VM удается выбросить исключение, не будучи ранее убитым ОС?

4b9b3361

Ответ 1

В среде Unix, в которой деление на ноль signal ведется через SIGFPE, JVM установит обработчик сигнала, который перехватит SIGFPE и, в свою очередь, throw a ArithmeticException. Если вы заинтересованы в внутренних компонентах, см., Например, man signal

Я полагаю, что запрос OP основан на том факте, что до тех пор, пока не будет обработчик SIGFPE, большинство процессов примет действие по умолчанию при получении этого сигнала, который должен завершиться. Таким образом, например, программа C

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

... если он даже компилируется, будет убит действием по умолчанию SIGFPESIG_DFL. Обработчик JVM вместо этого выделяет (catch способный) RuntimeException, поэтому эти исключения могут обрабатываться с помощью наглядного представления.

Как указывали некоторые другие, и только для полноты, на самом деле SIGFPE, сгенерированный из ядра, обычно отображается из специального прерывания от самого процессора; таким образом, "конвейер" - это что-то вроде

  • Прерывание прерывания ошибки CPU → обработчик прерываний ядра → SIGFPE SIG_DFL → процесс смерти

или

  • Прерывание прерывания ошибки процессора → обработчик прерывания ядра → обработчик SIGFPE в JVM → RuntimeException ArithmeticException в коде пользователя

На платформах, отличных от Unix, обработка аналогична.

Ответ 2

Java обрабатывает ситуацию как любой другой язык. Ошибка деления на нуль генерирует исключение процессора, которое вызывает прерывание. Прерывание "считывается" операционной системой и отправляется в программу, если обработчик зарегистрирован. Поскольку Java регистрирует обработчик, он получает ошибку и затем переводит ее в ArithmeticException, который перемещается вверх по стеку.

Ответ 3

JVM ловит раздел с помощью Zero, как это, на 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;
}

Скомпилируйте и запустите его:

[email protected]:~$ gcc -o catch_sigfpe myc.c

[email protected]:~$ ./catch_sigfpe
signal is 8
JVM throws an ArithmeticException here...

[email protected]:~$

Операционная система синхронно вызывает исключение SIGFPE, программа 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

Ответ 4

OS посылает сигнал процессу. Обработчик по умолчанию остановит процесс, но вы можете определить для него собственный обработчик. Я уверен, что java VM делает.