Anonymous & File-backed Page: 두 가지 페이지의 차이
가상 메모리의 페이지는 크게 Anonymous page와 File-backed page로 나뉜다. 둘을 가르는 핵심 질문은 “이 페이지의 원본을 누가 책임지는가?” 이다.
1. Anonymous Page (익명 페이지)
“태어나서 처음엔 0만 담긴 백지를 받고, 나중에 필요해지면 스왑 장치에 임시로 메모를 남기는 종이”
1-1. 정의
백업 파일이 없는 사용자 가상 페이지다. 어떤 파일에도 연결되지 않으며, 내용은 오직 프로세스가 직접 만든다.
1-2. 주로 쓰이는 곳
- 힙(Heap):
malloc(),brk()/sbrk()로 확장된 영역 - 스택(Stack): 함수 호출, 지역 변수, 스택 자동 확장
- BSS: 초기값이 0인 전역·정적 변수
1-3. 초기 로딩
- 페이지 폴트 발생
- 커널이 새 프레임 할당 (
palloc등) - Zero-fill — 프레임 전체를 0으로 채움
- PTE 갱신 (Present = 1)
1-4. 추방(Eviction)과 복원
- 프레임이 부족하면 swap device에 4KB 블록 단위로 기록하고, 위치를
page->anon.swap_slot에 저장한다 - 다시 접근하면 swap 슬롯에서 읽어 프레임을 재생성한다 (
swap_in)
| 장점 | 단점 |
|---|---|
| 생성·파괴가 빠르고 단순 (zero-fill) | 스왑 I/O 부담 (백업이 swap뿐) |
| 프로세스마다 독립적인 공간 | 다른 프로세스와 공유 불가 (동일 내용이라도 중복) |
정리하면, Anonymous page는 “복원시켜 줄 원본 파일이 없다”는 뜻이고, 그래서 스왑 장치가 실질적 백업이 된다.
2. File-backed Page
“이미 원본 파일이 있는 종이의 사본. 필요하면 원본을 다시 떼어오고, 수정하면 원본에 덮어쓰거나 폐기한다”
2-1. 정의
파일 시스템 블록을 백업 스토어로 삼는 가상 페이지다 (실행 파일, 공유 라이브러리, mmap()한 일반 파일 등).
2-2. 주로 쓰이는 곳
- 코드(Text)/데이터(Data) 세그먼트: ELF 로더가 lazy-load
- 공유 라이브러리: 여러 프로세스가 같은 read-only 프레임을 공유
- Memory-Mapped File:
mmap()으로 매핑해 버퍼처럼 직접 사용
2-3. 초기 로딩
- 페이지 폴트 발생
- 새 프레임 할당
file_read_at()으로 해당 오프셋 데이터를 읽어 채움 (남는 바이트는 0-fill)- PTE 갱신
2-4. 추방(Eviction)과 복원
| 상태 | 동작 |
|---|---|
| Clean (수정 안 됨) | 프레임을 그냥 버림 → 나중에 파일에서 다시 읽으면 됨 |
| Dirty (수정됨) | 쓰기 가능한 매핑이면 파일에 write-back. (읽기 전용 매핑에서 dirty가 나지 않도록 PTE의 R/W 비트를 미리 제한) |
| 장점 | 단점 |
|---|---|
| Clean 페이지는 I/O 없이 드롭 → 캐시처럼 동작 | Dirty 페이지 관리 복잡 (write-back 시점·동기화) |
| 여러 프로세스 간 공유·중복 제거 가능 (코드 세그먼트) | 파일 시스템 락·I/O 지연의 영향 |
정리하면, File-backed page는 “이미 파일이 백업 스토어로 존재한다”는 뜻이다. OS는 이를 활용해 I/O 횟수를 줄이고, 여러 프로세스가 같은 데이터(코드 등)를 안전하게 공유한다.
3. 왜 ‘익명’과 ‘파일’로 나눌까?
| 기준 | Anonymous | File-backed |
|---|---|---|
| 백업 스토어 | 원본이 없어 swap이 유일한 백업 | 이미 디스크에 존재 → 불필요한 I/O 절감 |
| 보호·공유 | 변경이 잦고 사적이라 안전하게 분리 | read-only 코드는 모든 프로세스가 하나의 물리 프레임 공유 → 메모리 절약 |
| 성능 | zero-fill이 간단하고 빠름 | clean page drop으로 페이지 캐시 hit/evict가 빠름 |
핵심은 “누가 너의 원본을 책임지냐?” 다. 원본 없음 → 익명 + 스왑 / 원본 파일 → 파일 + 캐시·write-back
4. 한눈에 보는 차이점
| 구분 | Anonymous page | File-backed page |
|---|---|---|
| 초기 내용 | 0으로 채우거나(zero-fill) swap에서 가져옴 | 실제 파일 블록(ELF 텍스트/데이터, mmap) |
| 영속성 | 프로세스 종료 시 사라짐. 변경분을 따로 저장하지 않으면 디스크에 안 남음 | 원본 파일이 근본. 읽기 전용이면 버려도 되고, 쓰기 가능 매핑이면 dirty를 파일에 write-back |
| 교체(Eviction) | 프레임 부족 시 swap device의 빈 슬롯에 페이지 전체 기록 | clean → 그냥 버림 / dirty → 파일에 쓰기 (쓰기 권한 없는 매핑이면 swap 사용 가능) |
| 대표 영역 | Heap, user stack, brk/sbrk 확장 영역, BSS | 실행 파일 코드·데이터, 공유 라이브러리, mmap된 파일 |
PintOS page->operations |
anon_page_ops → swap_in, swap_out, destroy |
file_page_ops → swap_in(=file_read_at), swap_out(dirty면 file_write_at), destroy |
| 스왑 슬롯 필요? | 예 (page->anon.swap_slot) |
대개 불필요(파일이 백업). 단, 쓰기 가능 매핑에서 dirty 후 evict 시 swap 사용 가능 |