Demand Paging은 프로그램의 모든 페이지를 미리 메모리에 올리지 않고, 실제로 필요해질 때만 로드하는 방식이다.
이로 인해 발생하는 Page Fault는 디스크 I/O를 동반하므로 비용이 매우 크며, 이를 최소화하기 위해 Page Replacement 알고리즘, Swap Space, Copy-On-Write 같은 기법이 사용된다.
Paging은 외부 단편화를 해결했지만, 새로운 문제가 생겼다.
이 관찰에서 출발한 개념이 Demand Paging이다.
프로세스의 페이지를 미리 적재하지 않고,
해당 페이지가 참조되는 순간에만 메모리로 가져오는 방식이다.
핵심 개념
Demand Paging은 가상 메모리가 실제로 가능해지는 전제 조건이다.
페이지 폴트가 발생했을 때의 전체 흐름은 다음과 같다.
[CPU 논리 주소 접근]
↓
[Page Table 검사]
↓ (Invalid)
[Page Fault 발생]
↓
[디스크에서 페이지 위치 탐색]
↓
[Free Frame 확보]
├─ 있으면 사용
└─ 없으면 Page Replacement
↓
[디스크 → 메모리 로드]
↓
[Page Table 갱신 (Valid = 1)]
↓
[Instruction Restart]

메모리와 디스크의 속도 차이는 압도적이다.
즉, 페이지 폴트 한 번은
수천 번의 메모리 접근 비용과 맞먹는다.
그래서 Demand Paging 시스템의 목표는
Page Fault Rate를 극단적으로 낮추는 것
Demand Paging의 성능은 EAT로 표현된다.
EAT = (1 - p) × Memory Time
+ p × Page Fault Service Time
p = 0.001 (0.1%)일 때도 EAT가 40배 이상 느려짐
➡ 페이지 폴트율은 0.01% 이하가 되어야 시스템 성능 유지 가능.
Swap Space: 디스크 공간 중 일부를 메모리 확장 공간처럼 사용하는 영역
특히 중요한 점은 다음이다.
👉 Dirty Bit 관리가 성능에 직접적인 영향을 미친다.
Page Replacement 발생
↓
이 페이지가 Dirty인가?
↓
┌───────────────┐
│ Dirty Page │ → Swap Space에 저장(write-back) 후 제거
└───────────────┘
┌───────────────┐
│ Clean Page │ → 그냥 버림 (no I/O)
└───────────────┘
Page의 상태
├─ RAM에 있음 → Frame에 매핑
├─ 디스크에 있음 → Swap Space
└─ 그냥 버려짐 → Clean Page (코드 영역 등)
fork() 시 부모 프로세스의 페이지를 즉시 복사하지 않음
→ 부모와 자식이 같은 물리 메모리를 공유함(Read-Only)
부모·자식 모두 같은 페이지 공유 (Write 불가 = Read-only)
둘 중 하나가 해당 페이지에 Write 요청
그 순간 페이지를 복사(copy)
→ 이후 독립적으로 사용
장점
fork 시 전체 주소 공간을 복사하는 비용 절약
메모리 사용량 감소
프로세스 생성 속도 대폭 향상
Page Fault 발생 시:
이때 선택 기준이 Page Replacement Algorithm이다.
교체할 페이지(Victim Page) 선정
해당 페이지가 Dirty이면 → 디스크에 저장(write-back)
Dirty 아니면 → 그냥 버림
새로운 페이지를 메모리로 로드
Page Table 업데이트
■ 의미
페이지가 메모리에 올라온 후 수정되었는지 여부 표시
Dirty Page:
교체 시 반드시 디스크에 다시 기록해야 함 (비용 ↑)
Clean Page:
교체해도 디스크에 기록할 필요 없음 (비용 ↓)
프레임 수를 늘렸는데
오히려 페이지 폴트가 증가하는 현상.
👉 비교 기준(하한선)으로만 사용
LRU가 강력한 이유는 하나다.
프로그램의 메모리 접근에는 패턴이 있다.
최근에 사용한 데이터는 곧 다시 사용됨
접근한 주소 근처를 곧 접근함
LRU는 이 특성을 가장 잘 활용한다.
Demand Paging은 필요한 페이지를 그때그때 메모리에 올리는 방식이며, Page Fault를 최소화하는 것이 핵심 목표다. 실제 OS는 정확한 LRU 대신 Clock 기반 근사 알고리즘을 사용하고, Thrashing을 방지하기 위해 Working Set과 PFF를 함께 고려한다. 커널 메모리는 Buddy System과 Slab Allocator로 별도 관리된다.
문제점:
문제점:
➡ 정확한 LRU는 OS 전체에 적용하기엔 너무 비싸다.
[Page A][Page B][Page C][Page D]
↑
Clock Hand
동작:
직관:
| R | Dirty | 의미 |
|---|---|---|
| 0 | 0 | ⭐최적의 교체 대상 |
| 0 | 1 | write-back 필요 |
| 1 | 0 | 최근 접근 |
| 1 | 1 | 최악의 교체 대상 |
OS는 (0,0)부터 우선 탐색한다.
Thrashing이란
페이지 교체가 너무 빈번해 CPU가 실제 작업을 거의 못 하는 상태다.
증상:
원인:
프로세스는 일정 시간 동안 집중적으로 사용하는 페이지 집합을 가진다.
이를 Working Set이라 한다.
Σ WS(processes) > 총 프레임 수
→ Thrashing 발생
대응:
Working Set 계산이 복잡하므로 Page Fault Rate로 간접 제어한다.
| 구분 | Local | Global |
|---|---|---|
| 교체 범위 | 자기 프레임 | 전체 프레임 |
| 간섭 | 없음 | 있음 |
| 효율 | 낮음 | 높음 |
| 위험 | 안정적 | Thrashing 위험 |
Global 정책은 WS/PFF와 함께 사용해야 안전하다.
유저 메모리와 달리 커널은 연속 메모리를 요구한다.
예: task_struct, file descriptor