메모리 구조
📋 문서 버전
이 문서는 5개의 버전이 있습니다. 현재 최신 버전을 보고 있습니다.
메모리 구조
개요
메모리 구조(Memory Layout)는 컴퓨터 시스템에서 프로그램이 실행될 때 메모리가 어떻게 구성되고 사용되는지를 설명하는 개념이다. 프로그램이 메모리에 적재되면, 그 프로그램은 여러 영역으로 나뉘어 데이터와 코드를 저장하며, 각 영역은 특정한 목적과 생명 주기를 가진다. 메모리 구조를 이해하는 것은 프로그래밍, 특히 시스템 프로그래밍, 성능 최적화, 보안 취약점 분석(예: 버퍼 오버플로우) 등에 매우 중요하다.
이 문서에서는 일반적인 프로세스 메모리 레이아웃의 구성 요소와 각 영역의 역할, 특징, 그리고 실제 예시를 중심으로 설명한다. 본 내용은 주로 유닉스 계열 운영체제(Unix-like OS)와 C 언어 기반의 실행 환경을 기준으로 한다.
메모리 레이아웃의 주요 영역
프로세스가 실행될 때 운영체제는 해당 프로세스를 위한 가상 메모리 공간을 할당하며, 이 공간은 다음과 같은 주요 영역으로 나뉜다:
- 텍스트 영역 (Text Segment)
- 초기화된 데이터 영역 (Initialized Data Segment)
- 초기화되지 않은 데이터 영역 (BSS Segment)
- 힙 (Heap)
- 스택 (Stack)
이들 영역은 일반적으로 아래에서 위로 또는 위에서 아래로 확장되며, 운영체제와 아키텍처에 따라 배치 순서가 다를 수 있다.
텍스트 영역 (Text Segment)
- 용도: 실행 가능한 기계어 코드(프로그램의 명령어)를 저장.
- 특징:
- 읽기 전용(read-only)이며, 실행 권한이 있음.
- 여러 프로세스가 동일한 프로그램을 실행할 경우, 이 영역은 공유될 수 있음.
- 컴파일 시 결정되며, 실행 중에 변경되지 않음.
- 예시:
main()함수, 사용자 정의 함수의 바이너리 코드.
int main() {
printf("Hello, World!\n"); // 이 코드는 텍스트 영역에 저장됨
return 0;
}
초기화된 데이터 영역 (Data Segment)
- 용도: 프로그램 시작 전에 값이 할당된 전역 변수와 정적 변수를 저장.
- 특징:
- 읽기/쓰기 가능.
- 프로그램 로딩 시 초기값이 메모리에 복사됨.
- 예시:
int global_var = 10; // 초기화된 전역 변수
static int static_var = 20; // 초기화된 정적 변수
초기화되지 않은 데이터 영역 (BSS Segment)
- 용도: 초기값이 지정되지 않은 전역 및 정적 변수를 저장.
- 특징:
- 프로그램 시작 시 0으로 자동 초기화됨.
- 실제 초기값을 저장하지 않으므로, 실행 파일 크기를 줄이는 데 유리.
- 이름은 "Block Started by Symbol"에서 유래.
- 예시:
int uninitialized_global; // BSS 영역에 배치됨
static int static_uninit; // 마찬가지로 BSS
힙 (Heap)
- 용도: 동적 메모리 할당을 위한 영역.
- 특징:
[malloc](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/C%EC%96%B8%EC%96%B4/malloc)(),[calloc](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/C%EC%96%B8%EC%96%B4/calloc)(),[realloc](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/C%EC%96%B8%EC%96%B4/realloc)(),[free](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/C%EC%96%B8%EC%96%B4/free)()등의 함수를 통해 관리.- 수명 주기가 명시적으로 관리됨 (개발자가 해제해야 함).
- 프로그램 실행 중에 확장/축소 가능.
- 단편화(fragmentation) 문제가 발생할 수 있음.
- 예시:
int *ptr = (int*)malloc(sizeof(int) * 100); // 힙에 메모리 할당
// 사용 후 반드시 free(ptr); 호출 필요
스택 (Stack)
- 용도: 함수 호출 시 지역 변수, 매개변수, 반환 주소 등을 저장.
- 특징:
- LIFO(Last In, First Out) 구조.
- 함수 진입 시 프레임이 푸시되고, 종료 시 팝됨.
- 자동으로 메모리 관리됨 (스코프 벗어나면 소멸).
- 크기가 제한되어 있으며, 스택 오버플로우 발생 가능.
- 예시:
void func(int x) {
int local = x * 2; // local 변수는 스택에 저장됨
}
메모리 레이아웃의 시각적 표현
일반적인 32비트 리눅스 프로세스의 메모리 레이아웃은 다음과 같은 형태를 가진다:
높은 주소
+------------------+
| 스택 | ↓ 확장
+------------------+
| ... |
+------------------+
| 힙 | ↑ 확장
+------------------+
| BSS |
+------------------+
| Data |
+------------------+
| Text |
+------------------+
낮은 주소
- 스택은 높은 주소에서 낮은 주소 방향으로 확장.
- 힙은 낮은 주소에서 높은 주소 방향으로 확장.
- 중간 영역은 고정된 크기의 데이터 영역들로 구성.
관련 개념 및 주의사항
가상 메모리와 물리 메모리
모든 프로세스는 가상 메모리 주소 공간을 가지며, 운영체제와 MMU(Memory Management Unit)를 통해 물리 메모리에 매핑된다. 이는 메모리 보호, 격리, 효율적인 사용을 가능하게 한다.
보안 이슈
- 버퍼 오버플로우: 스택이나 힙에 데이터를 초과하여 쓰면 인접 영역이 손상될 수 있으며, 악성 코드 실행로 이어질 수 있음.
- 스택 스매싱(Stack Smashing): 반환 주소를 덮어써서 제어 흐름을 조작하는 공격.
- ASLR(Address Space Layout Randomization): 메모리 영역의 시작 주소를 랜덤화하여 공격 난이도를 높임.
참고 자료
- Silberschatz, A., Galvin, P. B., & Gagne, G. (2018). Operating System Concepts (10th ed.). Wiley.
- Bryant, R. E., & O'Hallaron, D. R. (2016). Computer Systems: A Programmer's Perspective (3rd ed.). Pearson.
- Linux Programmer's Manual (
man 3 malloc,man 2 brk) - GNU C Library Documentation
이 문서는 컴퓨터 시스템의 메모리 구조에 대한 기초적 이해를 제공하며, 시스템 프로그래밍 및 저수준 소프트웨어 개발에 필수적인 지식을 다룹니다.
이 문서는 AI 모델(qwen-3-235b-a22b-instruct-2507)에 의해 생성된 콘텐츠입니다.
주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.