페이지를 이해했다면,
이제 세그먼트(Segment) 개념도 자연스럽게 받아들일 수 있다.
참고자료 🌼
CSAPP 9장 | 가상 주소 → 물리 주소 변환
[손필기] PPN, PTE, VPO | 가상주소 → 물리주소 변환
쉽게말하면, 데이터를 단순히 " 크기 "로 쪼갠 것이 페이지이고,
데이터를 "의미/역할"에 따라 나눈 것이 세그먼트다.
정글 캠퍼스에서 예를 들자면.
따라서 세그먼트는 페이지보다 더 큰 의미 단위로 볼 수 있다.
세그먼트는 예전에는 메모리 보호와 논리적 구조화를 위해 자주 사용됐지만,
현대 OS에서는 페이징을 기본으로 하고 세그먼트는 최소화하는 경우가 많다고 한다.
하지만 여전히 "코드 영역", "데이터 영역", "스택 영역" 등은
프로그램이 구동될 때 논리적 세그먼트로 나눠서 관리한다.
실제로 OS에서 세그먼트와 페이지가 어떻게 구성되어 있는지 살펴보자.
현대 운영체제에서는 "세그먼트 + 페이지" 방식을 같이 사용한다.
운영체제는 프로그램을 크게 논리적 세그먼트로 나눈다.
| 세그먼트 종류 | 역할 |
|---|---|
| 코드(Code) | 프로그램 명령어 (기계어) 저장 |
| 데이터(Data) | 전역 변수, static 변수 저장 |
| 힙(Heap) | 동적 메모리 할당 영역 (malloc 등) |
| 스택(Stack) | 함수 호출 시 생성되는 지역 변수 등 |
운영체제는 이 세그먼트들을 실제 메모리에 올릴 때
고정 크기(4KB 등)의 페이지로 쪼갠다.
"논리적으로 세그먼트 → 물리적으로 페이지" 구조라고 보면 된다!
| 단계 | 설명 |
|---|---|
| 논리적 구분 | 세그먼트 (코드, 데이터, 스택, 힙) |
| 실제 메모리 배치 | 고정 크기(4KB) 페이지로 쪼개서 관리 |
세그먼트 → 힙 메모리 구조로
앞서 살펴봤듯이,
운영체제는 프로그램을 논리적으로 세그먼트 단위로 나누어 관리한다.
그중에서도 우리는 특히 힙(Heap)이라는 영역에 주목해야 한다.
프로그램 실행 중에 필요할 때마다 메모리를 "동적으로" 할당받기 위해 사용되는 메모리 구역이다.
쉽게 말하면, 프로그램이 처음부터 "나는 무조건 1GB 쓸거야!" 이렇게 예약하는 게 아니라
필요한 만큼만 요청해서 쓰고,
다 쓰면 반납하는 방식이다.
필요할 때 malloc() 같은 함수를 통해 메모리를 빌려쓰고,
다 쓴 후에는 free()를 통해 반납하는 것이다.
✅ 전역 변수는 데이터 세그먼트에,
✅ 지역 변수는 스택 세그먼트에 저장되지만,
✅ malloc()으로 만든 메모리는 힙 세그먼트에 저장된다.

malloc(), free() 같은 함수를 통해 메모리를 직접 관리한다.💬 참고: 스택(stack)은 반대로 높은 주소 → 낮은 주소로 자라난다.
그래서 둘이 충돌하지 않도록 설계가 필요하다!
그렇다면 힙이 메모리를 실제로 어떻게 할당할까?
가장 기본적으로 사용하는 함수가 있다.
malloc() 호출
sbrk() 시스템 콜heap에 빈 공간이 없으면, 운영체제(OS) 에게 새로운 메모리를 요청한다.
이때 사용하는 게 바로 sbrk(size) 시스템 콜이다.
sbrk()는 운영체제에게 "힙(heap) 끝주소를 size만큼 늘려주세요!"라고 요청하는 함수다.
프로그램이 직접 메모리를 늘리는 게 아니라, 운영체제에 공식적으로 부탁하는 거다.
운영체제는 최종 보스다.
사용자 프로그램이 운영체제까지 가서 무언가를 요청하는 순간,
우리는 이를 "시스템 콜(System Call)" 이라고 부른다.
시스템콜 참고자료 🌼
CSAPP 8장 | 예외는 어떻게 정의되고, 어떻게 처리될까?
CSAPP 8장 번외편 | 운영체제, 커널, CPU, 시스템 콜 정리
free() 호출malloc과 free는 단순히 메모리를 빌려쓰고 반납하는 것처럼 보이지만,
내부에서는 heap 공간을 관리하고, 필요할 때는 운영체제에 시스템 콜을 통해 메모리를 요청하는 치밀한 관리가 이루어진다.
