Я бы предположил, что память для исключений выделяется так же, как и для всех других объектов (в куче).
Раньше это было проблемой, потому что тогда вы не можете выделить память для OutOfMemoryError,
вот почему не было трассировки стека до Java 1.6 . Теперь они также предварительно выделяют место для трассировки стека.
Если вам интересно, где хранится ссылка на исключение , пока она генерируется, JVM сохраняет ссылку внутри, пока она раскручивает стек вызовов, чтобы найти обработчик исключения, который затем получает ссылку (в своем стековом фрейме, как и любая другая локальная переменная).
Не может быть двух исключений, генерируемых одновременно (в одном потоке). Они могут быть вложенными, но тогда у вас есть только одно «активное» исключение со ссылкой на вложенное исключение.
Когда все ссылки на исключение исчезают (например, после завершения обработчика исключения), исключение собирается как мусор, как и все остальное.