Segmentation
Segmentation (세그먼테이션)
📝 기존 방식의 문제점
비효율적인 메모리 할당
문제:
- Heap과 Stack 사이의 사용하지 않는 공간도 할당
- 메모리 공간 낭비
- 큰 주소 공간에 프로세스 지원 불가
- Code 공간에 중복 발생
해결: Segmentation
🔑 Segmentation이란?
가상 주소 공간을 세그먼트 단위로 실제 메모리에 독립적으로 매핑
세그먼트: 메모리에서 일정 부분
일반적 구성: Code, Stack, Heap (3개 세그먼트)
✅ Segmentation의 장점
1. 메모리 공간 낭비 제거
2. 더 많은 주소 공간 지원
3. Code 공유로 메모리 절약
🔄 주소 변환 방법
가상 주소 구성
가상 주소 = Segment ID + Offset
Segment ID: 상위 2비트
Offset: 하위 12비트
변환 과정 (Heap 예시)
가상 주소: 0x4068
1. Segment ID 추출
→ 01 (Heap)
2. Offset 계산 (16진수 → 10진수)
→ 0x068 = 104
3. Segmentation Fault 확인
→ Offset(104) < Bound(2K) ✅
4. 물리 주소 계산
→ Base + Offset
→ 26KB + 104
코드 구현
// 상위 2비트 추출
Segment = (VirtualAddress & SEG_MASK) >> SEG_SHIFT
// 하위 12비트로 offset 추출
Offset = VirtualAddress & OFFSET_MASK
// Segmentation Fault 확인
if (Offset >= Bounds[Segment])
RaiseException(PROTECTION_FAULT)
else
PhysAddr = Base[Segment] + Offset
Register = AccessMemory(PhysAddr)
📚 Stack의 특별한 처리
Stack의 특징
성장 방향: 거꾸로 확장 (Negative)
Base 위치: 가장 높은 주소
계산 방식: Base - Offset
Stack 변환 과정
가상 주소: 0xA00
1. Segment ID 추출
→ 10 (Stack)
2. Offset 계산
→ 0xA00 = 2560
3. Segmentation Fault 확인
→ Offset(2560) < Bound(3K) ✅
4. 물리 주소 계산
→ Base - Offset
→ 36KB - 2560
🔗 Code Sharing
다중 프로세스가 Code 세그먼트 공유 가능
권한:
- ✅ 읽기 가능
- ✅ 실행 가능
- ❌ 값 변경 불가
목적: 메모리 절약
⚠️ Segmentation의 문제점
1. Context Switch
문제: 세그먼트 레지스터 관리
해결: Base & Bound 레지스터 값 저장/복원
2. 세그먼트 크기 변경
상황: Heap 공간 부족
해결: sbrk() system call 사용
sbrk(): Heap을 늘리거나 줄이는 함수
3. 외부 단편화 (External Fragmentation)
문제:
- 프로세스마다 크기가 다름
- 세그먼트 크기도 모두 다름
- 외부가 잘게 쪼개짐
예시:
전체 여유 공간: 24KB (16KB + 4KB + 4KB)
요청 크기: 20KB
→ 할당 불가 (인접하지 않음)
🔧 외부 단편화 해결 방법
1. Compaction
방법: 기존 세그먼트 재배치
장점: 여유 공간 통합
단점: 비용 발생, 성능 저하
2. Paging (페이징)
방법: 고정 크기 세그먼트 사용
장점: 외부 단편화 제거
단점: 내부 단편화 발생
내부 단편화 예시:
요청: 15KB
할당: 8KB × 2 = 16KB
낭비: 1KB
📊 정리
Segmentation의 목적
Heap과 Stack 사이 공간 낭비 해결
세그먼트 단위로 분리하여 효율성 증대
Segmentation의 한계
외부 단편화 문제 발생
해결책: Paging 기법 도입
❓ 면접 질문 예시
Q1. Segmentation은 무엇이고, 어떤 장점이 있나요?
답변: Segmentation은 가상 주소 공간을 세그먼트 단위(Code, Stack, Heap)로 실제 메모리에 독립적으로 매핑하는 방식입니다. Heap과 Stack 사이의 사용하지 않는 공간을 제거하여 메모리 공간 낭비를 막고, 더 많은 주소 공간을 지원할 수 있으며, Code를 공유하여 메모리를 절약할 수 있습니다.
Q2. Segmentation에서 주소 변환은 어떻게 하나요?
답변: 가상 주소는 Segment ID와 Offset으로 구성됩니다. 상위 2비트로 Segment ID를 추출하고, 하위 12비트로 Offset을 계산합니다. Offset이 Bound보다 작은지 확인하여 Segmentation Fault를 방지하고, Base + Offset으로 물리 주소를 계산합니다. Stack은 거꾸로 확장되므로 Base - Offset으로 계산합니다.
Q3. Segmentation의 문제점과 해결 방안은?
답변: Segmentation의 가장 큰 문제점은 외부 단편화입니다. 프로세스마다 크기가 다르기 때문에 세그먼트 크기도 모두 달라 메모리가 잘게 쪼개집니다. 이를 해결하기 위해 Compaction으로 세그먼트를 재배치하거나, Paging 기법으로 고정 크기 세그먼트를 사용합니다. Paging은 외부 단편화를 제거하지만 내부 단편화가 발생합니다.
Q4. Stack 세그먼트는 왜 특별하게 처리하나요?
답변: Stack은 Code와 Heap과 달리 거꾸로 확장되기 때문입니다. Code와 Heap은 Sign이 Positive이지만 Stack은 Negative입니다. Stack 세그먼트의 Base는 가장 높은 주소에서 시작하며, 물리 주소 계산 시 Base - Offset으로 계산합니다.
Q5. Code Sharing은 어떻게 동작하나요?
답변: Segmentation은 추가적인 하드웨어 지원을 통해 주소 공간 사이에서 Code 세그먼트를 공유할 수 있습니다. 다중 프로세스가 Code 세그먼트를 공유하여 메모리를 절약할 수 있으며, 읽고 실행은 가능하지만 값을 변경할 수는 없습니다.
📚 원본 참고 자료
출처: 2023-CS-Study
- 파일: os_segmentation.md
- 내용: Segmentation, 주소 변환, 외부 단편화
추가 학습 자료
🔗관련 문서
이 개념과 함께 학습하면 좋은 문서들입니다.