Как работает обработка исключений на уровне виртуальной машины Java

Источник: Java Perfomance (Hunt & John, 2011) 

Виртуальные машины Java используют исключения в качестве сигнала о том, что программа нарушила некие семантические ограничения языка. Например, попытка получить доступ к индексу за пределами массива вызовет ошибку. Исключение провоцирует нелокальное перемещение контроля из точки возникновения или “выброса”, в точку, которая была определена разработчиком. Интерпретатор HotSpot VM, его JIT-компиляторы и другие компоненты совместно реализуют механизм исключений.

Обработка исключений делится на два базовых случая:

  1. Исключение выбрасывается и перехватывается в одном и том же методе;
  2. Исключение перехватывается в методе-инициаторе вызова, то есть выше по стеку;

Второй случай сложнее и требует раскручивания стека вызовов для поиска подходящего обработчика. Исключения могут вызываться байт-кодом, возвратом из внутреннего вызова виртуальной машины, возвратом из JNI-вызова или Java-вызова. Последний вариант на самом деле является конечным пунктом для первых трёх. Когда виртуальная машина фиксирует исключение, вызывается HotSpot VM Runtime, цель которого – поиск ближайшего подходящего обработчика. Для этого используются данные о текущем методе, байт-коде и о самом объекте исключения. Если в текущем методе не удается найти подходящий обработчик, верхушка текущего стека вызовов снимается и процесс последовательно повторяется для предыдущих вызовов. Как только подходящий обработчик находится, состояние виртуальной машины обновляется и она перемещается к его выполнению.