자바 애플리케이션을 효율적으로 개발하고 메모리 누수를 방지하기 위해서는 JVM(Java Virtual Machine)의 메모리 관리 방식을 이해해야 한다. JVM 메모리 영역은 크게 스태틱(Static), 스택(Stack), 힙(Heap) 영역 등으로 나뉜다. 그중에서도 프로그램 실행 시 데이터 저장과 할당이 가장 활발하게 일어나는 핵심 영역이 바로 Stack과 Heap이다.
Stack 영역은 메서드 호출 시 생성되는 스레드(Thread)별 전용 메모리 공간이다. 정적(Static) 메모리 할당 방식을 사용하며, LIFO(Last In, First Out; 후입선출) 구조로 동작한다.
java.lang.StackOverflowError가 발생한다.Heap 영역은 JVM이 관리하는 동적 메모리 할당 공간이다. 모든 스레드가 공유하는 영역으로, 자바 프로그램 실행 중 동적으로 생성되는 객체들이 거주하는 공간이다.
new 연산자를 통해 생성된 모든 객체(Object)와 배열(Array)이 실제 데이터로 저장된다.java.lang.OutOfMemoryError가 발생한다.실제 코드에서 두 영역은 서로 긴밀하게 연결되어 동작한다. 예를 들어 다음과 같은 코드가 있다고 가정해 보자.
public void example() {
int age = 25;
String name = new String("Java");
}
int age = 25;: 기본 타입 변수인 age와 그 값 25는 Stack 영역에 저장된다.String name = new String("Java");: 참조 변수인 name은 Stack 영역에 생성되지만, new 키워드로 생성된 실제 "Java" 문자열 객체는 Heap 영역에 할당된다. Stack의 name 변수는 Heap에 있는 객체의 메모리 주소를 가리킨다.| 구분 | Stack 영역 | Heap 영역 |
|---|---|---|
| 저장 데이터 | 원시 타입 값, 참조 변수(주소값), 지역 변수 | 실제 객체(Instance) 및 배열 |
| 할당 방식 | 컴파일 타임 크기 결정 (정적) | 런타임 동적 할당 |
| 스레드 공유 | 각 스레드 독립 공간 (공유 X) | 모든 스레드 공유 |
| 해제 방식 | 메서드 종료 시 자동 해제 | 가비지 컬렉터(GC)에 의해 해제 |
| 속도 및 크기 | 속도 매우 빠름 / 크기 제한적 | Stack에 비해 속도 느림 / 크기 큼 |
자바의 Stack과 Heap은 데이터의 성격과 생명주기에 따라 역할을 분담한다. Stack은 빠른 접근과 자동 메모리 관리를 바탕으로 함수 실행 단위의 변수를 처리하고, Heap은 크기가 유동적인 객체를 저장하며 가비지 컬렉터를 통해 관리된다.