Java의 예외 생성 비용은 비싸다
Java에서 ControllerAdvice를 통한 계층적 커스텀 예외를 사용하던 중이었다.
최상위 예외인 BusinessException에 대해 여러 블로그에서 fillInStackTrace()을 사용하는 것을 보고 더 공부해보기로 했다.
JVM Exception 처리 순서

- 예외 발생
- 예외 발생 시, JVM은 예외 객체를 생성하고 예외를 발생시킨 메서드의 호출 스택을 추적
- 예외 객체 전파
- JVM은 예외를 발생시킨 메서드에서 예외 처리 코드를 찾는다. 예외 처리 코드가 없는 경우, 예외 객체를 호출하여 스택의 상위 메서드로 전파시킴
- 예외 처리
- 예외 객체가 상위 메서드로 전파되면, 해당 예외를 처리할 수 있는 catch 블록을 찾고, 없으면 다시 상위로 전파
- 예외 처리 실패
- 최상위 메서드에서도 처리할 catch 블록이 없을 경우 JVM은 예외 처리 실패로 결정하고, DefaultExceptionHandler를 통해 예외 처리
- DefaultExceptionHandler 실행
- 예외 객체의 정보를 출력하고 해당 예외를 처리하거나 스냅샷 정보를 수집하여 디버깅을 위한 정보 제공
예외 비용이 생기는 원인
호출 스택 탐색 과정 뿐 아니라 fillInStackTrace()를 통해 순회하며 클래스명, 메서드명 등의 정보를 모으는 과정의 비용이 훨씬 크기 때문이다.
fillInStackTrace()는 Throwable 클래스에 정의된 구현 메서드이다.

예외 생성 시, 1~5 ms를 소비하기 때문에 매우 큰 비용이다. 이 수치는 대략적인 수치로 메서드의 depth, JVM 상태에 따라 얼마든지 달라질 수 있다.
해결