메모리 구조
기술노트
💻 프로그램 메모리 구조
프로그램이 실행될 때, 운영체제(OS)는 정해진 방식에 따라 메모리를 여러 영역으로 나누어 할당합니다. 이 공간을 프로그램 메모리 구조라고 부르며, 각 영역은 저마다의 역할과 특징을 가집니다.
📂 4가지 메모리 영역
코드(Code) 영역
실행할 프로그램의 코드가 기계어 형태로 저장되는 공간입니다. CPU는 이 영역의 명령어를 순차적으로 가져가 처리하며, 데이터는 읽기만 가능하고 수정할 수는 없습니다.
- 저장 정보 : 소스 코드가 컴파일된 기계어
- 특징 : 읽기 전용(Read-Only)
데이터(Data) 영역
프로그램이 시작될 때 생성되어 종료될 때까지 유지되는 변수들이 저장됩니다. 주로 프로그램 전체에서 사용되는 전역 변수나 static 변수가 여기에 해당합니다.
- 저장 정보 : 전역 변수, 정적(static) 변수
- 생명 주기 : 프로그램 시작부터 종료까지
힙(Heap) 영역
프로그래머가 원하는 시점에 동적으로 메모리를 할당하고 해제하는 공간입니다. Java에서 `new` 키워드로 객체를 생성하면 바로 이 힙 영역에 저장됩니다. 사용이 끝난 메모리는 직접 해제해주어야 하며, 그렇지 않으면 '메모리 누수(Memory Leak)'가 발생할 수 있습니다.
- 저장 정보 : 동적으로 생성된 객체, 인스턴스
- 특징 : 개발자가 직접 관리, 런타임에 크기 결정
스택(Stack) 영역
함수가 호출될 때 생성되는 지역 변수와 매개변수가 임시로 저장되는 공간입니다. 함수 실행이 끝나면 저장되었던 데이터도 자동으로 사라지는 '후입선출(LIFO)' 구조를 가집니다. 속도가 매우 빠르다는 장점이 있습니다.
- 저장 정보 : 함수 내의 지역 변수, 매개변수
- 특징 : 함수 종료 시 자동 소멸, 빠른 속도
🔥 스택 vs 힙 비교
구분 | 스택 (Stack) | 힙 (Heap) |
---|---|---|
관리 주체 | OS (자동) | 개발자 (수동) |
속도 | 매우 빠름 | 상대적으로 느림 |
생명 주기 | 함수 호출 ~ 종료 | 직접 해제 전까지 |
크기 | 작고 제한적 | 크고 유연함 |
⚠️ 메모리 오버플로우
오버플로우는 각 영역이 할당된 메모리 공간을 넘어서는 현상입니다. 스택과 힙은 서로 마주보는 방향으로 메모리가 쌓이기 때문에, 한쪽이 너무 커지면 상대 영역을 침범하며 오버플로우가 발생할 수 있습니다.
- 스택 오버플로우 : 스택 공간이 부족하여 힙 영역을 침범하는 현상입니다. 주로 재귀 함수가 무한히 호출되거나 거대한 크기의 지역 변수를 선언했을 때 발생합니다.
- 힙 오버플로우 : 힙 영역이 부족하여 스택 영역을 침범하는 현상입니다.
💡 개발자 핵심 Point
- 프로그램 메모리는 역할에 따라 코드, 데이터, 힙, 스택 4가지 영역으로 나뉩니다.
- 스택(Stack)은 자동으로 관리되고 속도가 빠르지만, 크기가 작아 함수 내의 임시 데이터 저장에 주로 사용됩니다.
- 힙(Heap)은 개발자가 직접 관리하며 크기가 유연하여, 프로그램 전반에서 사용될 객체나 인스턴스를 저장하는 데 쓰입니다.
- 재귀 호출 시에는 종료 조건을 명확히 하여 스택 오버플로우가 발생하지 않도록 주의해야 합니다.