가상 메모리 (Virtual Memory)

핵심 인사이트 (3줄 요약)

물리 메모리(RAM)보다 큰 주소 공간을 제공하는 메모리 관리 기술로, 디스크를 메모리처럼 사용하여 프로그램이 연속된 주소 공간을 사용하는 것처럼 보이게 한다. MMU와 페이지 테이블로 가상→물리 주소 변환을 수행하며, TLB로 변환 속도를 높인다. 프로세스 격리, 메모리 보호, 효율적 메모리 활용의 핵심 기술이다.


Ⅰ. 개요 (필수: 200자 이상)

개념: 가상 메모리(Virtual Memory)는 물리 메모리(RAM)와 보조기억장치(디스크)를 결합하여, 물리 메모리보다 큰 주소 공간을 프로그램에 제공하는 메모리 관리 기술이다. 각 프로세스는 독립적인 가상 주소 공간을 가지며, MMU(Memory Management Unit)가 가상 주소를 물리 주소로 변환한다.

💡 비유: 가상 메모리는 **"책상 + 책장 시스템"**과 같다. 책상(RAM)이 작아도 책장(디스크)에 책을 보관해두고, 필요할 때마다 꺼내서 책상에서 볼 수 있다. 책상이 꽉 차면 안 보는 책을 책장으로 옮긴다. 내 책상은 내 것만 사용하듯, 각 프로그램도 자신만의 가상 공간을 가진다.

등장 배경 (필수: 3가지 이상 기술):

  1. 기존 문제점 - 물리 메모리 한계: 과거에는 프로그램 전체가 메모리에 올라가야 실행 가능했다. 4MB 프로그램을 실행하려면 4MB RAM이 필수였다. 멀티태스킹 시 메모리 부족으로 여러 프로그램을 동시에 실행할 수 없었다.
  2. 기술적 필요성: 프로그램의 **지역성(Locality)**을 활용하면, 전체 프로그램 중 실제 사용하는 부분만 메모리에 올려도 된다. 주소 변환을 통해 불연속적인 물리 메모리를 연속적인 가상 공간처럼 보이게 할 수 있다.
  3. 시장/산업 요구: 프로세스 격리로 보안 강화, 메모리 오버커밋으로 효율적 리소스 사용, 공유 메모리로 프로세스 간 통신 등이 필요했다.

핵심 목적: 물리 메모리 크기 제약을 극복하고, 각 프로세스에 독립적이고 보호된 주소 공간을 제공하여 시스템 안정성과 효율성을 보장하는 것이다.


Ⅱ. 구성 요소 및 핵심 원리 (필수: 가장 상세하게)

구성 요소 (필수: 최소 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가장 오래 안 쓴 것 교체★ 성능 우수구현 복잡★ 많이 사용
ClockReference 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-faultPage 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가지 관점):

  1. 기술적:

    • 페이지 크기 선택 (4KB vs 2MB vs 1GB)
    • Swappiness 값 설정 (0~100)
    • TLB 크기 및 associativity
    • NUMA 토폴로지 고려
  2. 운영적:

    • 스왑 공간 크기 (RAM의 1~2배)
    • OOM Killer 정책 설정
    • 메모리 사용량 모니터링
    • Page Fault 통계 수집
  3. 보안적:

    • ASLR (Address Space Layout Randomization)
    • NX 비트 (No-Execute)로 코드 실행 방지
    • Kernel Space와 User Space 격리
    • Side-channel 공격 방지 (Meltdown, Spectre)
  4. 경제적:

    • 물리 메모리 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가지 관점):

  1. 기술 발전 방향:

    • 5단계 페이지 테이블: 57비트 가상 주소 (128PB)
    • PKS (Protection Key Supervisor): 커널 메모리 세분화 보호
    • Memory Tagging: ARM MTE로 메모리 안전성 강화
  2. 시장 트렌드:

    • 컨테이너/Kubernetes에서의 메모리 격리 강화
    • Unikernel로 페이지 테이블 단순화
    • Persistent Memory의 가상 메모리 통합
  3. 후속 기술:

    • 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권밖에 못 담아요. 😢

가상 메모리를 쓰면: 책상이 작아도 **책장(디스크)**을 함께 사용해요!

  1. 지금 보는 책만 책상에 올려요
  2. 안 보는 책은 책장에 넣어요
  3. 다른 책이 필요하면 책장에서 꺼내고, 책상의 책을 넣어요
┌─────────────────────────────────────────┐
│  책상 (RAM): 작지만 빠름                │
│  ┌───┐ ┌───┐ ┌───┐                     │
│  │책1│ │책2│ │책3│ ← 지금 보는 책만    │
│  └───┘ └───┘ └───┘                     │
├─────────────────────────────────────────┤
│  책장 (디스크): 크지만 느림              │
│  [책4] [책5] [책6] [책7] [책8] ...      │
└─────────────────────────────────────────┘

장점:

  1. 많은 책을 볼 수 있어요 → 물리 메모리보다 큰 공간 사용
  2. 내 책상은 내 거예요 → 다른 사람이 책을 엉망으로 못 만듦 (보호)
  3. 필요한 것만 올려요 → 공간 절약

주소 변환은?

책의 "가상 위치"(내 머릿속 번호)와 "실제 위치"(책상/책장)가 달라요. **도서관 사서(MMU)**가 "5번 책 어디 있어요?" 하면 찾아줘요!

주의할 점: 책장에서 책을 꺼내는 건 느려요. 자주 꺼내는 책은 책상에 두세요! 📚