자바 프로그램을 실행하면 운영체제는 JVM에 일정량의 메모리를 할당합니다. JVM은 이 메모리를 두 영역으로 나누어 관리하는데, 하나는 스택(Stack) 메모리이고 다른 하나는 힙(Heap) 메모리입니다. 스택은 메서드 실행에 사용되고, 힙은 객체를 저장하는 데 사용됩니다. 스택이 가득 차면 JVM은 java.lang.StackOverflowError를 발생시키고, 힙이 가득 차면 java.lang.OutOfMemoryError를 발생시킵니다.
StackOverflowError란?
- 스택은 메서드 실행에 사용되는 메모리 영역입니다. 메서드가 호출될 때마다 스택 메모리에 하나의 블록(스택 프레임)이 생성됩니다.
- 이 블록에는 매개변수, 지역 변수, 객체 참조 등 해당 메서드와 관련된 데이터가 저장됩니다.
- 메서드의 실행이 끝나면 이 블록은 저장된 데이터와 함께 스택에서 제거됩니다.
- 즉, 호출된 모든 메서드는 반드시 실행을 마치고 스택 메모리를 떠나야 합니다.
- 그러나 메서드들이 계속 스택에 머물러 있으면 스택이 가득 차게 되고, 이때 JVM은
java.lang.StackOverflowError를 발생시킵니다. 대표적인 원인은 종료 조건 없이 자기 자신을 계속 호출하는 무한 재귀 호출입니다.
OutOfMemoryError란?
- 자바에서 생성한 객체들은 모두 힙 메모리에 저장됩니다. 더 이상 필요하지 않은 객체는 반드시 메모리에서 제거되어야 합니다.
- 가비지 컬렉터(Garbage Collector)가 힙 메모리에서 불필요한 객체들을 제거하는 역할을 담당합니다.
- 다만 가비지 컬렉터는 살아 있는 참조(live reference)를 가진 객체는 제거하지 않으며, 참조가 더 이상 존재하지 않는 객체만을 제거합니다.
- 따라서 불필요한 객체에 대한 참조가 계속 유지되면 메모리 누수(memory leak)가 발생할 수 있습니다.
- 힙 메모리에 새로운 객체를 위한 공간이 더 이상 남아 있지 않다면, JVM은
java.lang.OutOfMemoryError를 발생시킵니다.
핵심 차이점 요약
StackOverflowError는 스택 메모리가 부족할 때 발생하며, 주로 깊거나 무한한 재귀 호출이 원인입니다. 반면 OutOfMemoryError는 힙 메모리가 부족할 때 발생하며, 참조가 유지되어 가비지 컬렉션되지 못하는 객체가 너무 많을 때 주로 나타납니다. 두 오류를 정확히 구분하면 문제 발생 시 원인을 더 빠르게 진단하고 해결할 수 있습니다.