250701
하나의 프로그램이 실행되면 프로세스가 생성되고, 각 프로세스는 자신만의 독립적인 메모리 공간을 OS로부터 할당받는다.
이때 각 메모리 공간은 아래와 같이 4가지의 세그먼트로 분류된다.
(위에서부터 하위 주소, 아래로 갈수록 상위 주소)
Text
: 기계어, 즉 컴파일된 명령어 -> 읽기 전용Data
: 초기화된 변수 -> 실행 파일에 값 저장BSS
: 초기화되지 않은 변수 -> 실행 시 0으로 초기화Heap
: 런타임에 동적으로 할당된 메모리 -> 개발자가 명시적으로 할당/해제Stack
: 함수 호출 시 사용되는 임시 메모리, 이름처럼 상위에서 하위 방향(역순)으로 데이터 할당(LIFO 구조) -> 함수 호출에 따라 자동 생성/소멸
1번부터 3번까지는 정적 할당 영역이다. 따라서 프로그램의 실행과 종료에 따라 자동으로 생성 및 소멸된다.
그러나 4, 5번은 동적 할당 영역으로 개발자의 명령 혹은 함수 호출 상태에 따라 생성 및 소멸 시점이 달라진다.
이러한 특성으로, Heap
과 Stack
영역에는 아래와 같은 추가적인 특징이 있다.
Heap
영역
- 런타임에 크기가 결정되어 실행 중 동적으로 크기 확장 가능
- OS 가용 메모리 한계나 JVM의 최대 힙 크기 설정 값을 넘어가면
OutOfMemory: Java Heap Space
발생 가능
Stack
영역
- 프로세스 시작 시 고정된 크기만큼 할당됨
- 공간이 부족하면
StackOverFlow
발생 가능
이와 같은 세그먼트 방식은 논리적 주소를 (세그먼트 번호, offset) 형태로 표현하고, 이를 세그먼트 테이블의 base 주소와 더해 물리적 주소를 계산하기 때문에, 각 세그먼트의 크기와 접근 권한을 독립적으로 관리할 수 있어 메모리 보호와 오류 방지가 용이하다.