메모리 구조
📋 문서 버전
이 문서는 5개의 버전이 있습니다. 현재 버전 2을 보고 있습니다.
메모리 구조
개요
메모리 구조(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;
}
초기화된 데이터 영역 (Initialized Data Segment)
- 용도: 프로그램 시작 전에 초기값이 지정된 전역 변수와 정적 변수를 저장한다.
- 특징:
- 읽기/쓰기 가능하며, 프로그램 로딩 시 초기값이 메모리에 복사된다.
.data섹션으로도 불린다.- 예시:
int global_var = 10; static int static_var = 20;
초기화되지 않은 데이터 영역 (BSS Segment)
- 용도: 초기값이 지정되지 않은 전역 및 정적 변수를 저장한다.
- 특징:
- 프로그램 시작 시 자동으로 0으로 초기화된다.
- 메모리 공간은 할당되지만, 실행 파일에는 초기값이 저장되지 않아 파일 크기를 줄일 수 있다.
.bss섹션으로도 알려져 있다.- 예시:
int uninitialized_global; static int uninitialized_static;
힙 (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)()등의 함수를 통해 관리된다.- 프로그래머가 명시적으로 할당 및 해제를 제어한다.
- 아래에서 위로 확장되는 경우가 일반적이다.
- 메모리 누수(Memory Leak)나 이중 해제(Double Free) 등의 문제가 발생할 수 있어 주의가 필요하다.
- 예시:
int *ptr = (int*)malloc(sizeof(int) * 100);
스택 (Stack)
- 용도: 함수 호출 시 지역 변수, 매개변수, 반환 주소 등을 저장한다.
- 특징:
- LIFO(Last In, First Out) 구조를 따르며, 함수 진입 시 푸시, 종료 시 팝된다.
- 자동으로 관리되며, 함수가 종료되면 스택 프레임이 제거된다.
- 위에서 아래로 확장되는 경우가 일반적이다.
- 스택 오버플로우(Stack Overflow)는 무한 재귀나 큰 지역 배열로 인해 발생할 수 있다.
- 예시:
void func(int x) { int local = x * 2; // 스택에 저장됨 }
메모리 레이아웃의 시각적 표현
다음은 일반적인 32비트 리눅스 프로세스의 메모리 레이아웃을 나타낸다:
높은 주소
+------------------+
| 스택 | ← 위에서 아래로 확장
+------------------+
| ... |
+------------------+
| 힙 | ← 아래에서 위로 확장
+------------------+
| BSS |
+------------------+
| 데이터 |
+------------------+
| 텍스트 |
+------------------+
낮은 주소
참고: 64비트 시스템에서는 주소 공간이 훨씬 크며, 스택과 힙의 위치가 더 넓게 분리될 수 있다.
관련 개념 및 주의사항
가상 메모리와 물리 메모리
모든 프로세스는 가상 메모리 주소 공간을 가지며, 운영체제와 MMU(Memory Management Unit)를 통해 물리 메모리에 매핑된다. 이는 메모리 보호와 프로세스 격리를 가능하게 한다.
보안 이슈
- 버퍼 오버플로우: 스택이나 힙에 데이터를 초과하여 쓰면 인접 메모리가 손상될 수 있으며, 공격자가 텍스트 영역을 덮어 쓰는 형태의 코드 인젝션 공격이 가능하다.
- ASLR(Address Space Layout Randomization): 보안을 위해 메모리 영역의 시작 주소를 랜덤화하는 기법이다.
참고 자료
- Bach, Maurice J. (1986). The Design of the UNIX Operating System. Prentice Hall.
- Tanenbaum, Andrew S. (2007). Modern Operating Systems. Pearson Education.
- Linux Programmer's Manual (
man 3 malloc,man 3 free) - GNU C Library Documentation
이 문서는 컴퓨터 시스템의 메모리 구조에 대한 기본 이해를 제공하며, 시스템 프로그래밍 및 저수준 소프트웨어 개발에 필수적인 지식을 다룹니다.
이 문서는 AI 모델(qwen-3-235b-a22b-instruct-2507)에 의해 생성된 콘텐츠입니다.
주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.