핵심 인사이트 (3줄 요약)
- 본질: 세그멘테이션 (Segmentation)은 메모리를 같은 크기 조각이 아니라 코드, 데이터, 스택처럼 의미가 다른 논리 단위로 나누어 주소화하는 방식이다.
- 가치: 논리 단위별로 길이와 권한을 따로 둘 수 있어 보호 (Protection), 공유 (Sharing), 오류 검출을 사람의 프로그램 구조에 맞춰 설명하기 쉽다.
- 판단 포인트: 세그먼트 크기가 가변적이라 외부 단편화 (External Fragmentation)가 생기므로, 현대 운영체제는 순수 세그멘테이션보다 페이징 (Paging) 중심 구조에 선택적으로 결합한다.
Ⅰ. 개요 및 필요성
세그멘테이션은 프로세스의 주소 공간을 논리적 의미를 가진 여러 세그먼트로 나누어 관리하는 메모리 관리 방식이다. 같은 프로그램 안에서도 명령어 영역은 읽기 전용이어야 하고, 전역 데이터는 읽기/쓰기가 가능해야 하며, 스택은 호출 흐름에 따라 위아래로 변해야 한다. 세그멘테이션은 이 차이를 메모리 구조 자체에 반영해, "어디를 얼마나, 어떤 권한으로 쓸 수 있는가"를 하드웨어 수준에서 분리한다.
이 방식이 필요했던 이유는 초기 시스템에서 프로그램 전체를 하나의 연속 공간으로 다루면 보호와 공유가 지나치게 거칠어졌기 때문이다. 예를 들어 라이브러리 코드는 여러 프로세스가 함께 읽어도 되지만, 각 프로세스의 스택은 절대 섞이면 안 된다. 세그멘테이션은 이런 요구를 만족시키기 위해 프로그램을 사람이 이해하는 단위로 잘라 관리하려는 시도였다.
아래 그림은 세그멘테이션이 "같은 크기로 자르는 방식"이 아니라 "역할별로 다른 크기를 허용하는 방식"임을 보여준다.
┌────────────────────────────────────────────────────────────────────────────┐
│ 논리 구조 중심 분할: 세그먼트마다 의미와 길이가 다름 │
├───────────────────────────────┬────────────────────────────────────────────┤
│ 논리 주소 공간 │ 물리 메모리 배치 │
├───────────────────────────────┼────────────────────────────────────────────┤
│ Segment 0 : Code (24 KB) │ [ Code 24 KB ] │
│ Segment 1 : Data (10 KB) │ [ Free 6 KB ] ← 작은 빈틈 │
│ Segment 2 : Heap (18 KB) │ [ Data 10 KB ] │
│ Segment 3 : Stack (8 KB) │ [ Heap 18 KB ] │
│ │ [ Free 4 KB ] │
│ │ [ Stack 8 KB ] │
└───────────────────────────────┴────────────────────────────────────────────┘
핵심은 프로그램의 구조와 메모리 관리 단위가 서로 대응된다는 점이다. 대신 물리 메모리에서는 세그먼트 크기가 제각각이라 빈틈이 남기 쉬우며, 이 빈틈이 누적되면 외부 단편화 문제가 나타난다.
- 📢 섹션 요약 비유: 세그멘테이션은 서랍장을 양말칸, 셔츠칸, 서류칸처럼 용도별로 나누는 방식과 같다. 정리는 직관적이지만, 칸 크기가 제각각이면 남는 공간이 자꾸 애매하게 생긴다.
Ⅱ. 아키텍처 및 핵심 원리
세그멘테이션의 주소는 보통 세그먼트 번호 + 오프셋 (Offset)으로 표현된다. 메모리 관리 장치인 MMU (Memory Management Unit)는 세그먼트 번호로 세그먼트 테이블을 찾고, 그 안의 기준 주소와 길이, 권한 비트를 확인한 뒤 실제 물리 주소를 계산한다. 즉 세그멘테이션은 단순 위치 계산이 아니라 범위 검사와 권한 검사를 함께 수행하는 주소 변환 방식이다.
| 구성 요소 | 의미 | 핵심 역할 |
|---|---|---|
| 세그먼트 번호 | 어떤 논리 영역인지 식별 | 코드/데이터/스택 구분 |
| 오프셋 (Offset) | 해당 세그먼트 내부 위치 | 상대 위치 지정 |
| Base Register | 세그먼트 시작 물리 주소 | 실제 배치 위치 제공 |
| Limit Register | 세그먼트 길이 | 범위 초과 접근 차단 |
| Protection Bits | 읽기/쓰기/실행 권한 | 보호 정책 적용 |
아래 그림은 세그먼트 테이블을 이용한 주소 변환 흐름을 요약한다.
┌────────────────────────────────────────────────────────────────────────────┐
│ 세그먼트 주소 변환: 선택 → 검사 → 실제 주소 계산 │
├────────────────────────────────────────────────────────────────────────────┤
│ 논리 주소 = (s, d) │
│ │ │
│ ├─ s = Segment Number ────────┐ │
│ │ ▼ │
│ │ ┌────────────────────────────┐ │
│ │ │ Segment Table Entry[s] │ │
│ │ │ Base = 40,000 │ │
│ │ │ Limit = 8,192 │ │
│ │ │ Perm = Read / Write │ │
│ │ └────────────────────────────┘ │
│ │ │ │
│ └─ d = Offset ────────────────┼─ d < Limit ? ── No ─▶ Fault │
│ │ │
│ └─ Yes ──────────▶ Physical = Base + d │
└────────────────────────────────────────────────────────────────────────────┘
이 구조의 장점은 단순하다. 코드 세그먼트는 실행 가능하지만 쓰기 금지, 데이터 세그먼트는 읽기/쓰기 가능, 스택 세그먼트는 자동 확장 정책을 줄 수 있다. 반면 세그먼트 길이가 고정되지 않으므로 새 세그먼트를 넣거나 기존 세그먼트를 키울 때 연속 공간을 찾아야 하고, 이것이 메모리 압축 (Compaction) 비용과 외부 단편화를 부른다.
또한 범위를 벗어난 접근은 즉시 예외를 발생시킨다. 오늘날 우리가 흔히 말하는 세그멘테이션 폴트 (Segmentation Fault)는 역사적으로 이런 경계 위반 개념에서 출발했지만, 현대 시스템에서는 페이지 보호 위반까지 넓게 가리키는 이름으로 쓰이는 경우가 많다.
- 📢 섹션 요약 비유: 세그먼트 테이블은 건물 출입관리대장과 같다. 몇 층으로 갈지 확인하고, 허가된 구역인지 검사한 뒤, 맞으면 통과시키고 아니면 바로 출입을 막는다.
Ⅲ. 비교 및 연결
세그멘테이션을 제대로 이해하려면 페이징과의 차이를 같이 봐야 한다. 세그멘테이션은 프로그램 의미에 맞는 논리성을 얻는 대신 공간 배치가 어렵고, 페이징은 고정 크기 페이지로 나누어 배치 효율과 치환 관리를 쉽게 만드는 대신 프로그램 의미를 직접 드러내지는 못한다. 즉 둘의 차이는 단순히 "가변 vs 고정"이 아니라 무엇을 기준으로 메모리를 설명할 것인가의 차이다.
| 비교 항목 | 세그멘테이션 (Segmentation) | 페이징 (Paging) |
|---|---|---|
| 분할 기준 | 코드/데이터/스택 같은 논리 단위 | 동일한 크기의 페이지 |
| 크기 | 가변 길이 | 고정 길이 |
| 주소 의미 | 세그먼트 번호 + 오프셋 | 페이지 번호 + 오프셋 |
| 장점 | 보호/공유 정책이 직관적 | 할당·치환·프레임 관리가 단순 |
| 대표 단편화 | 외부 단편화 | 내부 단편화 |
| 현대 활용 | 제한적, 보조적 | 주력 메모리 관리 방식 |
운영체제 관점에서는 두 방식을 섞는 경우가 많다. 고전적 의미의 세그멘테이션은 프로세스 구조를 설명하는 데 유용하지만, 실제 물리 메모리 배치는 페이지 단위로 처리하는 편이 더 안정적이다. 그래서 현대 시스템은 "논리적 보호 경계"는 세그먼트 개념으로 이해하고, "실제 프레임 배치와 교체"는 페이징으로 수행하는 하이브리드 사고를 택한다.
x86 계열도 이런 흐름을 보여준다. 32비트 환경에서는 세그먼트 선택자와 디스크립터가 중요한 역할을 했지만, 64비트 장기 모드에서는 대부분의 세그멘테이션이 평면 주소 모델처럼 단순화되고 페이징이 중심이 된다. 다만 FS/GS 같은 일부 베이스는 스레드 로컬 저장소 (Thread-Local Storage)처럼 특정 목적에 여전히 활용된다.
- 📢 섹션 요약 비유: 세그멘테이션이 방 이름표를 붙여 공간의 의미를 살리는 설계라면, 페이징은 같은 크기 벽돌로 집을 빠르게 짓는 공법이다. 현대 시스템은 이름표는 남기고, 실제 시공은 규격 벽돌로 하는 쪽에 가깝다.
Ⅳ. 실무 적용 및 기술사 판단
실무에서 세그멘테이션은 순수 이론으로 끝나지 않는다. 첫째, 메모리 오류 분석에서는 "허용된 경계를 넘었는가"라는 사고방식이 여전히 핵심이다. 버퍼 오버런, 잘못된 포인터 역참조, 스택 침범은 모두 세그먼트적 보호 경계 개념으로 설명할 수 있고, 운영체제는 이를 예외로 바꾸어 프로세스를 중단한다.
둘째, 공유와 보호 정책 설계에서 세그먼트적 사고는 매우 유효하다. 예를 들어 공유 라이브러리는 여러 프로세스가 같은 코드 영역을 읽기 전용으로 매핑하여 메모리 사용량을 줄인다. 엄밀한 구현은 페이지 기반일지라도, 설계 설명은 "공유 가능한 코드 세그먼트"라는 표현이 가장 자연스럽다.
셋째, 기술사 관점의 판단 포인트는 "세그멘테이션을 어디까지 순수하게 유지할 것인가"다. 실시간성, 메모리 단편화, 압축 비용이 민감한 환경이라면 순수 세그멘테이션은 불리하다. 반대로 보호 경계 설명, 모듈 분리, 특권 수준 구분이 중요하다면 세그먼트 개념은 여전히 강력한 모델이 된다.
실무 판단 체크리스트
- 논리 경계별 권한 분리가 필요한가, 아니면 페이지 권한만으로 충분한가?
- 가변 크기 할당이 누적될 때 외부 단편화를 감당할 수 있는가?
- 메모리 압축이 필요한 구조라면 지연시간 급증을 허용할 수 있는가?
- 현대 CPU/OS에서 실제로 지원하는 세그멘테이션 기능 범위를 이해하고 있는가?
피해야 할 안티패턴
-
세그먼트 확장을 자주 요구하는 워크로드에 연속 물리 공간을 전제로 설계하는 것
-
세그멘테이션 폴트라는 이름만 보고 모든 오류 원인을 순수 세그먼트 위반으로 단정하는 것
-
현대 64비트 시스템에서도 고전 x86 세그멘테이션이 그대로 동작한다고 오해하는 것
-
📢 섹션 요약 비유: 세그멘테이션은 도시의 용도지역 지정과 같다. 주거지, 공장지대, 공원이 분리되면 관리가 쉬워지지만, 땅 모양이 제각각이면 재개발과 확장이 까다로워진다.
Ⅴ. 기대효과 및 결론
세그멘테이션의 가장 큰 효과는 주소 공간을 단순한 숫자 연속체가 아니라 의미 있는 구조로 바라보게 만든다는 점이다. 덕분에 보호, 공유, 오류 검출을 프로그램 구조와 연결해 설명할 수 있고, 시스템 보안 교육이나 메모리 모델 설계에서도 직관성이 높다. 특히 "코드는 실행 가능하지만 쓰기 금지", "데이터는 쓰기 가능하지만 실행 금지" 같은 사고는 세그멘트적 분리 철학과 맞닿아 있다.
그러나 순수 세그멘테이션만으로 현대 대규모 시스템을 운영하기는 어렵다. 외부 단편화가 누적되면 연속 공간 확보가 어려워지고, 메모리 압축은 성능과 예측 가능성을 해친다. 그래서 현대 운영체제는 세그멘테이션을 기본 배치 전략이라기보다, 보호 경계와 역사적 메모리 모델을 이해하는 핵심 개념으로 보아야 한다.
결국 세그멘테이션은 "메모리를 사람의 논리대로 설명하려는 방식"으로 기억하면 좋다. 오늘의 주력 구현은 페이징이지만, 메모리 보호와 주소 공간 의미를 설명하는 언어는 여전히 세그멘테이션의 철학 위에 서 있다.
- 📢 섹션 요약 비유: 세그멘테이션은 책장을 장르별로 나누는 사서의 방식이다. 찾고 보호하기는 쉬워지지만, 책 크기가 제각각이면 선반 공간을 딱 맞춰 쓰기는 어려워진다.
📌 관련 개념 맵
| 개념 | 연결 포인트 |
|---|---|
| MMU (Memory Management Unit) | 세그먼트 번호를 해석하고 Base/Limit/권한 검사를 수행한다. |
| 페이징 (Paging) | 세그멘테이션의 외부 단편화 문제를 완화하기 위해 현대 시스템에서 결합된다. |
| 보호 비트 (Protection Bits) | 읽기/쓰기/실행 권한을 세그먼트 단위로 나누어 적용한다. |
| 세그멘테이션 폴트 (Segmentation Fault) | 허용 범위 또는 보호 정책을 위반했을 때 드러나는 대표적 오류 개념이다. |
| 스레드 로컬 저장소 (Thread-Local Storage) | 현대 x86-64에서 제한적으로 남아 있는 세그먼트 베이스 활용 사례다. |
📈 관련 키워드 및 발전 흐름도
연속 메모리 할당
│
▼
세그멘테이션 (Segmentation)
│
├─ 보호·공유 강화
│
└─ 외부 단편화 심화
│
▼
페이징 (Paging) 결합
│
▼
현대 평면 주소 공간 + 페이지 기반 가상 메모리
│
▼
제한적 세그먼트 활용 (FS/GS, TLS, 보호 모델 이해)
이 흐름은 세그멘테이션이 폐기된 개념이 아니라, 순수 구현에서는 물러났지만 현대 가상 메모리와 보호 모델의 사고방식 안에 흡수되었음을 보여준다.
👶 어린이를 위한 3줄 비유 설명
- 세그멘테이션은 장난감을 블록, 인형, 자동차처럼 종류별 상자에 나눠 담는 거예요.
- 그래서 "이 상자는 같이 써도 돼", "저 상자는 망가지니 건드리면 안 돼" 같은 규칙을 쉽게 정할 수 있어요.
- 하지만 상자 크기가 다 다르면 창고에 넣을 때 자투리 공간이 많이 남을 수 있어요.