자바면 절대 안죽는다거나 절대 안죽는게 좋다는 생각 자체가 그냥 못배운 티가 난다.
자바에서 try-catch로 예외를 잡아도 시스템을 정상화할 수 없거나, 복구가 사실상 불가능한 상황들은 주로 JVM 수준의 리소스 고갈이나 논리적 데이터 오염과 관련이 있습니다.
이런 상황에서는 catch 블록을 작성하는 것 자체가 무의미하거나 오히려 위험할 수 있습니다. 대표적인 사례 4가지를 정리해 드립니다.
1. JVM 가상 머신 레벨의 오류 (java.lang.Error)
자바의 Error 계열은 Exception과 달리 애플리케이션 코드에서 복구하도록 설계된 것이 아닙니다.
OutOfMemoryError (OOM): JVM이 할당 가능한 메모리 한계를 넘었을 때 발생합니다. 이 시점에서 애플리케이션은 이미 객체를 생성할 수도, 새로운 연산을 수행할 수도 없습니다. catch를 해서 로그를 남길 수는 있어도, 그 즉시 프로그램이 죽는 것을 막을 방법은 없습니다.
StackOverflowError: 재귀 호출이 너무 깊어지면 발생합니다. 스택 프레임을 더 이상 생성할 수 없으므로, 현재 실행 흐름을 이어갈 방법이 없습니다.
NoClassDefFoundError / NoSuchMethodError: 런타임에 필요한 클래스나 메서드가 없다는 것은 빌드나 배포 환경 자체가 망가졌음을 의미합니다. 이는 코드 차원에서 고칠 수 없습니다.
2. 데이터 무결성 붕괴 (State Corruption)
비즈니스 로직 도중 치명적인 예외가 발생했을 때, 그 예외를 잡아버리면 '오염된 상태'가 영구적으로 남게 됩니다.
예시: 은행 계좌에서 돈을 출금할 때, "내 계좌에서 차감"은 성공했는데 "상대 계좌에 입금"하는 로직에서 DB 연결이 끊겨 SQLException이 발생한 경우입니다.
복구 불가능성: 이 예외를 catch로 잡고 "출금 실패했습니다"라고 사용자에게 알리기만 하면, 이미 내 계좌에선 돈이 나간 상태가 유지되어 데이터 불일치(Inconsistency)가 발생합니다. 트랜잭션 처리가 되어 있지 않다면, 애플리케이션은 이미 '정상적인 상태'를 벗어났으므로 복구가 불가능합니다.
3. 멀티스레드 교착 상태 (Deadlock)
자바의 멀티스레드 환경에서 여러 스레드가 서로의 자원을 점유하고 놓아주지 않는 '데드락' 상황입니다.
복구 불가능성: 자바 프로그램은 멈춰버리지만, Exception이 발생하지 않기 때문에 try-catch로도 감지할 수 없습니다. 스레드들이 영원히 기다리는 상태가 되며, 외부 모니터링 툴이 프로세스를 강제 종료하고 재시작하지 않는 한 애플리케이션은 스스로 복구할 방법이 없습니다.
4. 외부 시스템의 치명적 의존성 오류
애플리케이션은 정상인데, 외부 환경이 완전히 붕괴된 경우입니다.
상황: 애플리케이션이 의존하는 핵심 외부 서비스(예: 인증 서버, 중앙 DB)가 영구적으로 다운되거나, 보안 정책에 의해 차단된 경우.
복구 불가능성: catch로 반복해서 재시도(Retry)하는 것은 트래픽 낭비일 뿐, 시스템이 정상 서비스로 복귀하는 것과는 거리가 멉니다. 이때는 '복구'가 아니라 '서비스 서킷 브레이커(Circuit Breaker)'를 열고 실패를 인정하는 것이 최선입니다.
결론: 왜 "예외 처리"를 만능으로 보면 안 될까?
자바 개발자들 사이에서도 **"예외를 잡을 때, 정말로 복구할 수 있는 상황인지 고민하라"**는 격언이 있습니다.
복구 가능(Recoverable): 네트워크 일시적 끊김, 사용자 입력 값 오류 등. (이때는 try-catch가 유용)
복구 불가능(Unrecoverable): 메모리 부족, 데이터 무결성 파괴, 논리적 설계 오류. (이때는 빠르게 죽고, 시스템 인프라를 통해 재시작하는 것이 훨씬 안전)
러스트는 이러한 복구 불가능한 상황을 panic!이라는 강제 종료 메커니즘을 통해 "안전하지 않은 상태로 계속 돌아가는 것"을 시스템 레벨에서 원천 차단하는 철학을 가지고 있습니다. 반면 자바는 예외 처리에 너무 많은 자율권을 주다 보니, 오히려 개발자가 "복구할 수 없는 오류를 억지로 잡아서 시스템을 괴사시키는" 실수를 저지르기 쉽습니다.
- dc official App
러스트는 예외 처리가 없는게 사실입니까? 하지만 한 편으론 더 좋아보이는군요 컴파일단에서 빡세게 잡는다는거니까
아뇨 Result<T, err> 형태로 성공과 실패가 공존하는 타입에 대해서 무조건적으로 모든 경우를 처리하도록 문법차원에서 강요하기 때문에 예외처리보다 더 귀찮습니다. - dc App
@글쓴 프갤러(27.165) 귀찮음도 짊어져야하는게 개발자의 숙명아니겠습니까
@루도그담당(211.246) 그렇게 생각한다면 당신에게 딱맞는 프로그래밍 언어는 러스트입니다. - dc App
@글쓴 프갤러(27.165) 하지만 이미 cpp중이다노
리절트 타입을 리턴하지 않고 int 리턴 가능합니다. 러빨러들의 말은 항상 검증하며 들어야 합니다.
ai slop 글이라 안보고 내림
저능아들에겐 정성들일 필요가 없어서 - dc App
저 글에서 지적하는 내용들은 타 언어에서도 발생합니다. 러스트에서도 발생한다는 얘기입니다. 안전성은 개발자가 직접 챙겨야하는 것이고 언어로 도달할 수 있는 부분은 일부분입니다. 글쓴이는 특수화 일반화의 논리적 오류를 범하고 있습니다.
러스트로도 본문에 나온 문제점들을 방지할 수 없습니다. 언어로 한정할 때 러스트는 가용성 측면에서 불리하며 언어 외적으로 일반적 상황에서는 러스트든 자바든 언어가 안전을 담보하지 않습니다.
러스트 혹세무민, 곡학아세를 중단할 때입니다. ㅎㅎ