가상 메모리 (Virtual Memory)
핵심 인사이트 (3줄 요약)
물리 메모리(RAM)보다 큰 주소 공간을 제공하는 메모리 관리 기술로, 디스크를 메모리처럼 사용하여 프로그램이 연속된 주소 공간을 사용하는 것처럼 보이게 한다. MMU와 페이지 테이블로 가상→물리 주소 변환을 수행하며, TLB로 변환 속도를 높인다. 프로세스 격리, 메모리 보호, 효율적 메모리 활용의 핵심 기술이다.
Ⅰ. 개요 (필수: 200자 이상)
개념: 가상 메모리(Virtual Memory)는 물리 메모리(RAM)와 보조기억장치(디스크)를 결합하여, 물리 메모리보다 큰 주소 공간을 프로그램에 제공하는 메모리 관리 기술이다. 각 프로세스는 독립적인 가상 주소 공간을 가지며, MMU(Memory Management Unit)가 가상 주소를 물리 주소로 변환한다.
💡 비유: 가상 메모리는 **"책상 + 책장 시스템"**과 같다. 책상(RAM)이 작아도 책장(디스크)에 책을 보관해두고, 필요할 때마다 꺼내서 책상에서 볼 수 있다. 책상이 꽉 차면 안 보는 책을 책장으로 옮긴다. 내 책상은 내 것만 사용하듯, 각 프로그램도 자신만의 가상 공간을 가진다.
등장 배경 (필수: 3가지 이상 기술):
- 기존 문제점 - 물리 메모리 한계: 과거에는 프로그램 전체가 메모리에 올라가야 실행 가능했다. 4MB 프로그램을 실행하려면 4MB RAM이 필수였다. 멀티태스킹 시 메모리 부족으로 여러 프로그램을 동시에 실행할 수 없었다.
- 기술적 필요성: 프로그램의 **지역성(Locality)**을 활용하면, 전체 프로그램 중 실제 사용하는 부분만 메모리에 올려도 된다. 주소 변환을 통해 불연속적인 물리 메모리를 연속적인 가상 공간처럼 보이게 할 수 있다.
- 시장/산업 요구: 프로세스 격리로 보안 강화, 메모리 오버커밋으로 효율적 리소스 사용, 공유 메모리로 프로세스 간 통신 등이 필요했다.
핵심 목적: 물리 메모리 크기 제약을 극복하고, 각 프로세스에 독립적이고 보호된 주소 공간을 제공하여 시스템 안정성과 효율성을 보장하는 것이다.
Ⅱ. 구성 요소 및 핵심 원리 (필수: 가장 상세하게)
구성 요소 (필수: 최소 4개 이상):
| 구성 요소 | 역할/기능 | 특징 | 비유 |
|---|---|---|---|
| MMU (Memory Management Unit) | 가상→물리 주소 변환 | TLB, 페이지 테이블 워커 내장 | 도서관 사서 |
| 페이지 테이블 | 가상 페이지→물리 프레임 매핑 | 다단계 페이지 테이블로 공간 절약 | 도서 목록 카드 |
| TLB (Translation Lookaside Buffer) | 페이지 테이블 캐시 | 최근 변환 정보 저장, 95%+ 적중률 | 자주 찾는 책 위치 기억 |
| 페이지 (Page) | 가상 메모리 분할 단위 | 4KB~2MB, 고정 크기 | 책의 한 장 |
| 프레임 (Frame) | 물리 메모리 분할 단위 | 페이지와 동일 크기 | 책상 위 책 자리 |
| 스왑 영역 (Swap Space) | 디스크의 가상 메모리 공간 | 페이지 아웃된 데이터 저장 | 책장 |
구조 다이어그램 (필수: ASCII 아트):
┌─────────────────────────────────────────────────────────────────────────────┐
│ 가상 메모리 시스템 구조 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ 프로세스 가상 주소 공간 (32비트 예시) │ │
│ │ 0xFFFFFFFF ┌──────────────────────┐ │ │
│ │ │ 커널 영역 │ (사용자 접근 불가) │ │
│ │ ├──────────────────────┤ │ │
│ │ │ 스택 (Stack) ↓ │ 함수 호출, 지역 변수 │ │
│ │ │ ... │ │ │
│ │ │ │ │ │
│ │ │ 힙 (Heap) ↑ │ 동적 할당 (malloc) │ │
│ │ ├──────────────────────┤ │ │
│ │ │ BSS (초기화X) │ 전역 변수 (미초기화) │ │
│ │ ├──────────────────────┤ │ │
│ │ │ 데이터 (Data) │ 전역 변수 (초기화됨) │ │
│ │ ├──────────────────────┤ │ │
│ │ │ 코드 (Text) │ 실행 명령어 │ │
│ │ 0x00000000 └──────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ ↓ 가상 주소 접근 │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ MMU (주소 변환) │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ TLB (캐시) │ │ │
│ │ │ VPN │ PFN │ 권한 │ V │ D │ R │ │ │ │
│ │ │ 0x1 │ 0xF │ RW │ 1 │ 0 │ 1 │ ← Hit: 바로 변환 │ │ │
│ │ │ ... │ ... │ ... │...│...│...│ ← Miss: 페이지 테이블 조회 │ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ │ ↓ TLB Miss │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ 페이지 테이블 (메모리 내) │ │ │
│ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ VPN │ PFN │ V │ D │ R │ W │ X │ U │ │ │ │ │
│ │ │ ├─────┼─────┼───┼───┼───┼───┼───┼───┤ │ │ │ │
│ │ │ │ 0 │ 5 │ 1 │ 0 │ 1 │ 1 │ 0 │ 0 │ → 물리 프레임 5│ │ │ │
│ │ │ │ 1 │ - │ 0 │ - │ - │ - │ - │ - │ → 디스크! │ │ │ │
│ │ │ │ 2 │ 3 │ 1 │ 1 │ 1 │ 1 │ 0 │ 0 │ → 물리 프레임 3│ │ │ │
│ │ │ └─────────────────────────────────────────────────────┘ │ │ │
│ │ │ V:Valid, D:Dirty, R:Referenced, W:Write, X:Execute, U:User│ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ ↓ 물리 주소 │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ 물리 메모리 (RAM) │ │
│ │ Frame 0: [페이지 A] Frame 4: [페이지 E] │ │
│ │ Frame 1: [페이지 B] Frame 5: [페이지 0] ← 매핑됨 │ │
│ │ Frame 2: [페이지 C] Frame 6: [빈 공간] │ │
│ │ Frame 3: [페이지 2] Frame 7: [빈 공간] │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ ↓ Page Fault 시 │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ 스왑 영역 (디스크) │ │
│ │ [페이지 1] [페이지 D] [페이지 F] ... │ │
│ └───────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
주소 변환 과정 (32비트, 4KB 페이지):
┌─────────────────────────────────────────────────────────────────────────────┐
│ 가상 주소 (32비트): │
│ ┌─────────────────────────┬────────────────────────────────────────┐ │
│ │ VPN (20비트) │ Offset (12비트) │ │
│ │ 페이지 번호 │ 페이지 내 위치 │ │
│ │ 0x00001 │ 0x234 │ │
│ └─────────────────────────┴────────────────────────────────────────┘ │
│ ↓ │
│ 페이지 테이블 조회: VPN → PFN │
│ ↓ │
│ 물리 주소 (32비트): │
│ ┌─────────────────────────┬────────────────────────────────────────┐ │
│ │ PFN (20비트) │ Offset (12비트) ← 그대로 │ │
│ │ 물리 프레임 번호 │ 프레임 내 위치 │ │
│ │ 0x00005 │ 0x234 │ │
│ └─────────────────────────┴────────────────────────────────────────┘ │
│ 최종 물리 주소 = PFN × 4KB + Offset = 0x5234 │
└─────────────────────────────────────────────────────────────────────────────┘
동작 원리 (필수: 단계별 상세 설명):
① 가상 주소 생성 → ② TLB 조회 → ③ 페이지 테이블 조회 → ④ 물리 주소 접근 → ⑤ Page Fault 처리
-
1단계 - 가상 주소 생성:
- CPU가 가상 주소로 메모리 접근 요청
- 명령어의 주소 필드에서 가상 주소 추출
- VPN(Virtual Page Number)과 Offset으로 분리
-
2단계 - TLB 조회:
- TLB에서 VPN으로 PFN(Physical Frame Number) 검색
- TLB Hit: 바로 물리 주소 생성 (1~2 사이클)
- TLB Miss: 페이지 테이블로 이동
-
3단계 - 페이지 테이블 조회 (TLB Miss 시):
- 다단계 페이지 테이블 순회 (x86: 4단계)
- PML4 → PDPT → PD → PT 순으로 조회
- 각 단계별 메모리 접근 (4회 메모리 읽기)
- Valid 비트 확인: 1이면 PFN 획득, 0이면 Page Fault
-
4단계 - 물리 주소 접근:
- PFN + Offset으로 물리 주소 계산
- 캐시(L1→L2→L3) 조회 후 메모리 접근
- 데이터 반환 또는 쓰기 수행
-
5단계 - Page Fault 처리 (V=0 시):
- CPU 예외 발생 → OS Page Fault 핸들러 실행
- 디스크에서 해당 페이지 로드
- 빈 프레임 찾기 (없으면 교체 알고리즘 실행)
- 페이지 테이블 갱신, TLB 갱신
- 원래 명령어 재실행
핵심 알고리즘/공식 (해당 시 필수):
주소 변환 시간 계산:
┌─────────────────────────────────────────────────────────────────┐
│ EAT = TLB_Hit_Rate × (TLB_Time + Mem_Time) │
│ + TLB_Miss_Rate × (TLB_Time + PT_Time + Mem_Time) │
│ │
│ PT_Time = n × Mem_Time (n = 페이지 테이블 단계 수) │
├─────────────────────────────────────────────────────────────────┤
│ 예시: TLB 적중률 98%, TLB 1ns, 메모리 100ns, 4단계 PT │
│ EAT = 0.98 × (1 + 100) + 0.02 × (1 + 400 + 100) │
│ = 98.98 + 10.02 = 109ns │
│ (TLB 없으면: 400 + 100 = 500ns → 4.6배 느림) │
└─────────────────────────────────────────────────────────────────┘
페이지 교체 알고리즘:
┌─────────────────────────────────────────────────────────────────┐
│ Belady's Anomaly: FIFO에서 프레임↑가 Page Fault↑ 현상 │
│ 해결: LRU, Clock 알고리즘 사용 (Stack 알고리즘) │
├─────────────────────────────────────────────────────────────────┤
│ LRU (Least Recently Used): │
│ 교체 대상 = 가장 오랫동안 참조되지 않은 페이지 │
│ 구현: Counter, Stack, Reference Bit │
│ │
│ Clock Algorithm (Second Chance): │
│ Reference Bit이 1이면 0으로 설정하고 건너뜀 │
│ Reference Bit이 0이면 교체 │
│ 순환 큐로 구현 → 하드웨어 구현 용이 │
└─────────────────────────────────────────────────────────────────┘
코드 예시 (필수: Python 또는 의사코드):
# 가상 메모리 시뮬레이터
class VirtualMemory:
def __init__(self, physical_frames=16, page_size=4096):
self.page_size = page_size
self.num_frames = physical_frames
# 물리 메모리
self.physical_memory = [None] * physical_frames
# 페이지 테이블 (가상 페이지 → 물리 프레임 매핑)
self.page_table = {} # VPN -> {'pfn': int, 'valid': bool, 'dirty': bool}
# TLB (캐시)
self.tlb = {} # VPN -> PFN
self.tlb_size = 8
# 프레임 할당 관리
self.free_frames = list(range(physical_frames))
self.frame_to_vpn = {} # 역매핑 (교체용)
# 통계
self.tlb_hits = 0
self.tlb_misses = 0
self.page_faults = 0
self.disk_reads = 0
# LRU 리스트
self.lru_list = [] # 가장 최근 사용이 앞쪽
def translate(self, virtual_address):
"""가상 주소를 물리 주소로 변환"""
vpn = virtual_address // self.page_size
offset = virtual_address % self.page_size
# 1. TLB 조회
if vpn in self.tlb:
self.tlb_hits += 1
pfn = self.tlb[vpn]
self._update_lru(vpn)
return pfn * self.page_size + offset
# 2. TLB Miss - 페이지 테이블 조회
self.tlb_misses += 1
if vpn not in self.page_table or not self.page_table[vpn]['valid']:
# Page Fault!
self._handle_page_fault(vpn)
# 페이지 테이블에서 PFN 획득
pfn = self.page_table[vpn]['pfn']
# TLB 갱신
self._update_tlb(vpn, pfn)
# LRU 갱신
self._update_lru(vpn)
return pfn * self.page_size + offset
def _handle_page_fault(self, vpn):
"""페이지 폴트 처리"""
self.page_faults += 1
self.disk_reads += 1
# 빈 프레임이 있으면 할당
if self.free_frames:
pfn = self.free_frames.pop(0)
else:
# LRU로 교체 대상 선정
victim_vpn = self.lru_list.pop() # 가장 오래된 것
pfn = self.page_table[victim_vpn]['pfn']
# Dirty 페이지면 디스크에 쓰기
if self.page_table[victim_vpn]['dirty']:
self.disk_reads += 1 # 실제로는 disk write
# 페이지 테이블에서 제거
self.page_table[victim_vpn]['valid'] = False
# TLB에서도 제거
if victim_vpn in self.tlb:
del self.tlb[victim_vpn]
# 새 페이지 로드
self.page_table[vpn] = {
'pfn': pfn,
'valid': True,
'dirty': False,
'referenced': True
}
# 역매핑 갱신
self.frame_to_vpn[pfn] = vpn
# LRU 리스트에 추가
self.lru_list.insert(0, vpn)
def _update_tlb(self, vpn, pfn):
"""TLB 갱신"""
if len(self.tlb) >= self.tlb_size:
# FIFO로 교체
oldest = next(iter(self.tlb))
del self.tlb[oldest]
self.tlb[vpn] = pfn
def _update_lru(self, vpn):
"""LRU 리스트 갱신"""
if vpn in self.lru_list:
self.lru_list.remove(vpn)
self.lru_list.insert(0, vpn)
def read(self, virtual_address):
"""메모리 읽기"""
physical_address = self.translate(virtual_address)
pfn = physical_address // self.page_size
return self.physical_memory[pfn]
def write(self, virtual_address, data):
"""메모리 쓰기"""
physical_address = self.translate(virtual_address)
pfn = physical_address // self.page_size
self.physical_memory[pfn] = data
# Dirty Bit 설정
vpn = virtual_address // self.page_size
self.page_table[vpn]['dirty'] = True
def get_stats(self):
"""통계 반환"""
total = self.tlb_hits + self.tlb_misses
tlb_hit_rate = self.tlb_hits / total * 100 if total > 0 else 0
return {
'tlb_hits': self.tlb_hits,
'tlb_misses': self.tlb_misses,
'tlb_hit_rate': f"{tlb_hit_rate:.1f}%",
'page_faults': self.page_faults,
'disk_reads': self.disk_reads
}
# 사용 예시
vm = VirtualMemory(physical_frames=4, page_size=4096)
# 메모리 접근 패턴 (지역성 활용)
addresses = [0, 4096, 8192, 12288, 16384, 0, 4096, 32768, 0, 4096]
print("=== 가상 메모리 시뮬레이션 ===")
for addr in addresses:
phys = vm.translate(addr)
print(f"가상 {addr:#x} → 물리 {phys:#x}")
print(f"\n통계: {vm.get_stats()}")
# TLB Hit Rate가 높아질수록 성능 향상
Ⅲ. 기술 비교 분석 (필수: 2개 이상의 표)
장단점 분석 (필수: 최소 3개씩):
| 장점 | 단점 |
|---|---|
| 큰 주소 공간: 물리 메모리보다 큰 공간 사용 가능 | 페이지 폴트 오버헤드: 디스크 I/O는 수 ms 소요 |
| 프로세스 격리: 각 프로세스 독립적 주소 공간 | TLB 미스 비용: 다단계 페이지 테이블 조회 |
| 메모리 보호: 권한 비트로 접근 제어 | 메모리 오버헤드: 페이지 테이블 공간 필요 |
| 공유 메모리: Copy-on-Write로 효율적 공유 | 스래싱(Thrashing): 과도한 페이지 폴트 |
페이지 교체 알고리즘 비교 (필수: 최소 2개 대안):
| 알고리즘 | 원리 | 장점 | 단점 | 실제 사용 |
|---|---|---|---|---|
| FIFO | 먼저 들어온 페이지 교체 | 구현 간단 | Belady's Anomaly | 거의 안 씀 |
| LRU | 가장 오래 안 쓴 것 교체 | ★ 성능 우수 | 구현 복잡 | ★ 많이 사용 |
| Clock | Reference Bit 순환 확인 | LRU 근사, 구현 쉬움 | 부정확할 수 있음 | ★ 실제 사용 |
| Optimal | 미래에 가장 안 쓸 것 교체 | 이론적 최적 | 구현 불가능 | 성능 비교용 |
| LFU | 사용 빈도 가장 낮은 것 | 지역성 활용 | 초기 편향 | 캐시 |
| Working Set | 최근 사용 페이지 집합 유지 | 스래싱 방지 | 오버헤드 큼 | 연구용 |
★ 선택 기준: 실제 OS는 Clock 또는 LRU 근사 알고리즘을 사용. 정확한 LRU는 하드웨어 비용이 높아 실현 어렵다.
페이지 크기 비교:
| 페이지 크기 | 장점 | 단점 | 적합한 용도 |
|---|---|---|---|
| 4KB | 내부 단편화 적음, 유연함 | 페이지 테이블 큼, TLB 커버리지 작음 | 일반 용도 |
| 2MB (Huge) | TLB 커버리지 큼, 테이블 작음 | 내부 단편화 큼, 메모리 낭비 | DB, 대량 데이터 |
| 1GB | 초대형 TLB 커버리지 | 내부 단편화 매우 큼 | HPC, 빅데이터 |
Ⅳ. 실무 적용 방안 (필수: 기술사 판단력 증명)
기술사적 판단 (필수: 3개 이상 시나리오):
| 적용 분야 | 구체적 적용 방법 | 기대 효과 (정량) |
|---|---|---|
| 데이터베이스 서버 | Huge Pages(2MB) 활용, Swappiness=1 설정 | TLB 미스 90% 감소, 성능 20% 향상 |
| 컨테이너 환경 | cgroup으로 메모리 제한, OOM Killer 설정 | 메모리 격리로 안정성 확보 |
| 실시간 시스템 | mlockall()로 페이지 고정, Pre-fault | Page Fault 0회, 지연 1μs 이하 |
| 고성능 컴퓨팅 | NUMA-aware 할당, 대용량 페이지 | 대역폭 50% 향상, 지연 30% 감소 |
실제 도입 사례 (필수: 구체적 기업/서비스):
- 사례 1: Oracle Database - Huge Pages(2MB) 사용으로 SAG(System Global Area)의 TLB 미스 감소. TPC-C 벤치마크에서 15% 성능 향상.
- 사례 2: Redis 인메모리 DB - Transparent Huge Pages(THP) 활성화로 100GB+ 데이터셋에서 10% 지연 감소. 단, Copy-on-Write 시 주의 필요.
- 사례 3: 카카오 서버 - 컨테이너별 메모리 제한(cgroup)으로 스래싱 방지. OOM 발생 시 자동 재시작 정책 적용.
도입 시 고려사항 (필수: 4가지 관점):
-
기술적:
- 페이지 크기 선택 (4KB vs 2MB vs 1GB)
- Swappiness 값 설정 (0~100)
- TLB 크기 및 associativity
- NUMA 토폴로지 고려
-
운영적:
- 스왑 공간 크기 (RAM의 1~2배)
- OOM Killer 정책 설정
- 메모리 사용량 모니터링
- Page Fault 통계 수집
-
보안적:
- ASLR (Address Space Layout Randomization)
- NX 비트 (No-Execute)로 코드 실행 방지
- Kernel Space와 User Space 격리
- Side-channel 공격 방지 (Meltdown, Spectre)
-
경제적:
- 물리 메모리 vs 스왑 비용
- 디스크 I/O로 인한 성능 저하
- 메모리 오버커밋 위험
- Huge Pages의 메모리 낭비
주의사항 / 흔한 실수 (필수: 최소 3개):
- ❌ 스래싱 무시: Page Fault 빈도가 너무 높으면 시스템이 멈춤 → Working Set 모니터링 필요
- ❌ Huge Pages 남용: 작은 프로세스에 Huge Pages 쓰면 메모리 낭비 → 4KB와 혼용
- ❌ Copy-on-Write + THP: fork() 후 write 시 Huge Page 전체 복사 → THP 비활성화 고려
관련 개념 / 확장 학습 (필수: 최소 5개 이상 나열):
📌 가상 메모리 핵심 연관 개념 맵
┌─────────────────────────────────────────────────────────────────┐
│ 가상 메모리 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 페이지교체 ←──→ 가상메모리 ←──→ 메모리보호 │
│ ↓ ↓ ↓ │
│ TLB 페이지테이블 프로세스격리 │
│ ↓ ↓ ↓ │
│ 캐시메모리 스왑영역 컨텍스트스위치 │
│ │
└─────────────────────────────────────────────────────────────────┘
| 관련 개념 | 관계 | 설명 | 문서 링크 |
|---|---|---|---|
| TLB | 핵심 구성요소 | 페이지 테이블 캐시 | [TLB](./tlb.md) |
| 페이지 교체 | 핵심 알고리즘 | Page Fault 시 교체 대상 선정 | [페이지 교체](../02_operating_system/page_replacement.md) |
| 캐시 메모리 | 계층 구조 | 물리 메모리 접근 전 캐시 확인 | [캐시 메모리](./cache_memory.md) |
| 프로세스 관리 | 메모리 할당 | 각 프로세스별 가상 주소 공간 | [프로세스](../02_operating_system/process.md) |
| 스와핑 | 확장 기술 | 전체 프로세스를 디스크로 이동 | [스와핑](../02_operating_system/swapping.md) |
| 메모리 보호 | 보안 기능 | 권한 비트로 접근 제어 | [메모리 보호](./memory_protection.md) |
Ⅴ. 기대 효과 및 결론 (필수: 미래 전망 포함)
정량적 기대 효과 (필수):
| 효과 영역 | 구체적 내용 | 정량적 목표 |
|---|---|---|
| 메모리 활용 | 물리 메모리보다 큰 공간 사용 | 2~4배 오버커밋 가능 |
| 격리 | 프로세스별 독립적 주소 공간 | 보안 사고 99% 차단 |
| 효율성 | 지역성 활용 메모리 사용 | 실제 사용 20%만 로드 |
| 공유 | Copy-on-Write 메모리 공유 | 메모리 사용 50% 절감 |
미래 전망 (필수: 3가지 관점):
-
기술 발전 방향:
- 5단계 페이지 테이블: 57비트 가상 주소 (128PB)
- PKS (Protection Key Supervisor): 커널 메모리 세분화 보호
- Memory Tagging: ARM MTE로 메모리 안전성 강화
-
시장 트렌드:
- 컨테이너/Kubernetes에서의 메모리 격리 강화
- Unikernel로 페이지 테이블 단순화
- Persistent Memory의 가상 메모리 통합
-
후속 기술:
- CXL Memory: 확장 메모리를 가상 메모리로 통합
- Capability-based Addressing: 포인터 안전성 강화
- Single Address Space OS: 주소 공간 단순화
결론: 가상 메모리는 현대 운영체제의 핵심 기반 기술로, 메모리 관리, 보호, 격리를 동시에 제공한다. TLB 최적화, Huge Pages, NUMA 인식 등이 성능을 결정하며, CXL, Persistent Memory 등의 신기술과 통합되어 발전할 것이다.
※ 참고 표준: Intel 64 SDM Vol. 3 (Virtual Memory), ARM Architecture Reference Manual (VMSA), POSIX.1 (mmap, mlock)
어린이를 위한 종합 설명 (필수)
가상 메모리는 "책상 + 책장 시스템"이야!
학교에서 숙제를 하려고 해요. 책상(RAM)은 작은데 공부할 책이 많아요. 어떻게 할까요?
가상 메모리가 없다면: 책상이 꽉 차면 더 이상 공부를 못 해요. 10권의 책을 펼쳐놓고 싶어도 책상이 3권밖에 못 담아요. 😢
가상 메모리를 쓰면: 책상이 작아도 **책장(디스크)**을 함께 사용해요!
- 지금 보는 책만 책상에 올려요
- 안 보는 책은 책장에 넣어요
- 다른 책이 필요하면 책장에서 꺼내고, 책상의 책을 넣어요
┌─────────────────────────────────────────┐
│ 책상 (RAM): 작지만 빠름 │
│ ┌───┐ ┌───┐ ┌───┐ │
│ │책1│ │책2│ │책3│ ← 지금 보는 책만 │
│ └───┘ └───┘ └───┘ │
├─────────────────────────────────────────┤
│ 책장 (디스크): 크지만 느림 │
│ [책4] [책5] [책6] [책7] [책8] ... │
└─────────────────────────────────────────┘
장점:
- 많은 책을 볼 수 있어요 → 물리 메모리보다 큰 공간 사용
- 내 책상은 내 거예요 → 다른 사람이 책을 엉망으로 못 만듦 (보호)
- 필요한 것만 올려요 → 공간 절약
주소 변환은?
책의 "가상 위치"(내 머릿속 번호)와 "실제 위치"(책상/책장)가 달라요. **도서관 사서(MMU)**가 "5번 책 어디 있어요?" 하면 찾아줘요!
주의할 점: 책장에서 책을 꺼내는 건 느려요. 자주 꺼내는 책은 책상에 두세요! 📚