페이징 (Paging)
핵심 인사이트 (3줄 요약)
- 본질: 페이징(Paging)은 프로세스를 연속된 하나의 거대한 공간에 담아야 한다는 고정관념을 파괴하고, 물리 메모리와 논리 메모리를 모두 동일한 고정 크기(주로 4KB)의 블록으로 썰어서 아무렇게나 흩뿌려 맵핑하는 비연속 메모리 할당의 궁극적 해답이다.
- 가치: 프로그램 크기에 맞춰 자를 때 발생하던 가장 악성 찌꺼기인 외부 단편화(External Fragmentation)를 원천적으로 0%로 만들며, 압축(Compaction)이라는 끔찍한 오버헤드 연산을 운영체제 역사에서 지워버렸다.
- 융합: 논리 주소를 물리 주소로 이어주는 거대한 해독 장부인 **페이지 테이블(Page Table)**을 필수적으로 동반하며, 이 장부 검색의 지연을 막기 위해 **TLB(Translation Lookaside Buffer)**라는 하드웨어 캐시와 완벽하게 융합되어 현대 운영체제 메모리 관리의 유일신이 되었다.
Ⅰ. 개요 및 필요성 (Context & Necessity)
-
개념: 물리 메모리(RAM)를 고정된 크기의 빈 상자들인 **프레임(Frame)**으로 나누고, 논리 메모리(프로그램)를 똑같은 크기의 데이터 조각인 **페이지(Page)**로 나눈다. 그리고 어떤 페이지 조각이 어느 프레임 상자에 들어갔는지 매핑(Mapping) 해주는 기법이다.
-
필요성: 연속 메모리 할당(가변 분할)을 사용하던 시절, 메모리 중간중간에 10MB, 2MB씩 쓸모없는 공간이 남는 '외부 단편화' 때문에 시스템이 멈추곤 했다. 이를 해결하려고 메모리를 물리적으로 복사해 미는 '압축(Compaction)'을 했더니 시스템이 수 초간 정지(Freeze)했다. 더 이상 빈 공간을 '모으는' 방식으로는 다중 프로그래밍의 속도를 감당할 수 없었다. 아예 **"쪼개진 공간에 맞춰서 프로그램을 찢어버리자"**는 혁명적 발상이 필요했다.
-
💡 비유: 페이징은 거대한 백과사전(프로그램)을 낱장으로 다 찢어서 보관하는 것과 같다. 책장에 500페이지짜리 두꺼운 빈 공간(연속 할당)이 없어도, 그냥 빈틈 보일 때마다 낱장 한 장씩을 쑤셔 넣는다(페이징). 대신 사서(OS)가 "1페이지는 거실 책장 두 번째 칸에, 2페이지는 화장실 서랍에..."라고 목차(페이지 테이블)를 완벽하게 적어두어, 읽을 때 1초 만에 이어 붙여준다.
-
등장 배경 및 외부 단편화의 종말:
- 맞춤 재단의 한계: 가변 분할은 요구 크기에 딱 맞춰 자르려다 보니 필연적으로 자투리 공간(외부 단편화 33% 낭비)을 양산했다.
- 극단적인 고정 분할의 도입: 다시 옛날의 '고정 분할' 방식으로 돌아가되, 방 크기를 수십 MB가 아니라 현미경 수준인 4KB로 극단적으로 작게 고정해버렸다.
- 단편화의 멸종: 모든 프레임과 페이지가 4KB로 100% 동일한 규격을 가지므로, 남는 자투리 공간(외부 단편화) 자체가 수학적으로 발생할 수 없게 되었다. 빈 프레임이 있으면 그냥 넣으면 딱 맞는다.
┌────────────────────────────────────────────────────────────────────┐
│ 페이징의 시각적 구조 (페이지와 프레임의 1:1 매핑) │
├────────────────────────────────────────────────────────────────────┤
│ │
│ [ 논리 메모리 (CPU가 보는 가상 공간) ] │
│ ┌─────────┐ │
│ │ Page 0 │──┐ [ 페이지 테이블 (매핑 장부) ] │
│ ├─────────┤ │ ┌──────┬───────┐ │
│ │ Page 1 │──┼────▶│ Page │ Frame │ │
│ ├─────────┤ │ ├──────┼───────┤ │
│ │ Page 2 │──┼──┐ │ 0 │ 1 │ ──┐ │
│ ├─────────┤ │ │ │ 1 │ 4 │ ─┼─┐ │
│ │ Page 3 │──┘ │ │ 2 │ 3 │ ─┼┼─┼─┐ │
│ └─────────┘ │ │ 3 │ 7 │ ─┼┼─┼─┼─┐ │
│ │ └──────┴───────┘ ││ │ │ │ │
│ │ ││ │ │ │ │
│ [ 물리 메모리 (실제 RAM) ] ▼▼ ▼ ▼ ▼ │
│ ┌─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐ │
│ │ Frame 0 │ Frame 1 │ Frame 2 │ Frame 3 │ Frame 4 │ Frame 5 │ │
│ │ (빈 방) │ Page 0 │ (빈 방) │ Page 2 │ Page 1 │ (빈 방) │ │
│ └─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘ │
│ (Frame 7에 Page 3 있음 - 생략) │
└────────────────────────────────────────────────────────────────────┘
[다이어그램 해설] CPU는 여전히 프로그램이 0페이지부터 3페이지까지 예쁘게 한 줄로 붙어있다고 착각한다. 하지만 실제 물리 램에서는 1번 프레임, 4번 프레임 등 중구난방으로 흩어져 있다. 이 혼돈을 질서로 바꾸는 유일한 열쇠가 바로 한가운데 위치한 '페이지 테이블'이다. 이 테이블 덕분에 OS는 남는 프레임이 어디에 있든 전혀 상관없이 마음껏 테트리스를 할 수 있게 되었다.
- 📢 섹션 요약 비유: 이삿짐을 쌀 때 가구(프로그램)를 통째로 옮기려다 좁은 문(메모리 파편화)에 막히는 대신, 가구를 나사 단위(4KB 페이지)로 모조리 분해해서 상자(프레임)에 나눠 담고 나중에 조립 설명서(페이지 테이블)를 보고 합치는 기적의 수납술입니다.
Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)
논리 주소 번역 아키텍처 (Paging Hardware)
CPU가 뱉어내는 32비트(또는 64비트)의 긴 이진수 논리 주소는, 페이징 하드웨어(MMU)에 의해 두 부분으로 쪼개져 해석된다.
- p (Page Number, 페이지 번호): 페이지 테이블을 찾기 위한 인덱스 번호. (이 책의 몇 번째 장인가?)
- d (Page Offset, 오프셋): 해당 페이지 안에서 위에서부터 몇 번째 줄인가를 나타내는 변위. (그 장의 몇 번째 줄인가?)
┌─────────────────────────────────────────────────────────────────────┐
│ 논리 주소를 물리 주소로 번역하는 과정 (MMU) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ [ CPU 발출 논리 주소 ] │
│ ┌─────────┬──────────┐ │
│ │ p (3) │ d (1050) │ │
│ └─────────┴──────────┘ │
│ │ │ │
│ ▼ │ (오프셋은 그대로 물리 주소로 패스됨) │
│ [ 페이지 테이블 ] │ │
│ 인덱스(p) 프레임(f) │
│ ... ... │ │
│ 3 ──▶ 8 │ │
│ ... ... │ │
│ ▼ │
│ ┌─────────┬──────────┐ │
│ │ f (8) │ d (1050) │ │
│ └─────────┴──────────┘ │
│ [ 변환된 최종 물리 주소 (RAM 접근) ] │
└─────────────────────────────────────────────────────────────────────┘
[다이어그램 해설] 이 하드웨어 매커니즘의 가장 위대한 점은 '오프셋(d)'은 전혀 변하지 않고 통과(Bypass)한다는 것이다. 프레임의 크기와 페이지의 크기가 4KB로 완벽하게 동일하기 때문에, 페이지 내에서 1050번째 떨어진 데이터는, 물리 램 프레임 안에서도 정확히 1050번째 위치에 존재한다. MMU는 오직 방 번호(p)를 실제 아파트 동 번호(f)로 1:1 치환해 주는 작업만 수행하면 된다.
내부 단편화 (Internal Fragmentation)의 부활
페이징은 '외부 단편화'라는 악마를 죽였지만, '내부 단편화'라는 작은 도깨비를 다시 불러왔다.
-
프로그램 크기가 13KB고, 페이지 크기가 4KB라면?
-
4KB × 3장 = 12KB. 남은 1KB를 위해 어쩔 수 없이 4KB 프레임 1장을 더 할당해야 한다.
-
마지막 4번째 프레임 안에는 1KB만 데이터가 차고 3KB가 텅 비게 된다. 이 3KB는 그 어떤 프로세스도 쓸 수 없는 '내부 단편화'다.
-
하지만 수십 MB가 버려지던 외부 단편화에 비하면, 기껏해야 수 KB가 버려지는 내부 단편화는 현대의 기가바이트(GB) 급 램 환경에서는 애교 수준의 푼돈이므로 OS는 이를 쿨하게 무시한다.
-
📢 섹션 요약 비유: 택배를 보낼 때 무조건 똑같은 규격 4호 상자(4KB)만 쓰기로 규칙을 정했기 때문에, 상자 테트리스(외부 단편화 해결)는 완벽하게 되지만, 마지막 상자 안에는 물건 하나만 달랑 들어가서 뽁뽁이로 빈 공간(내부 단편화)을 채워야 하는 사소한 낭비가 발생합니다.
Ⅲ. 융합 비교 및 다각도 분석
비교 1: 페이징 (Paging) vs 세그멘테이션 (Segmentation)
비연속 할당의 두 맞수인 이 둘의 철학은 극명하게 갈린다.
| 비교 항목 | 페이징 (Paging) | 세그멘테이션 (Segmentation) |
|---|---|---|
| 분할 철학 | 기계 중심 (아무 의미 없이 그냥 4KB로 무식하게 멉) | 인간 중심 (함수, 배열 등 논리적 의미 단위로 예쁘게 자름) |
| 조각 크기 | 고정 크기 (동일함) | 가변 크기 (제각각임) |
| 단편화 종류 | 내부 단편화 발생 (외부는 0%) | 외부 단편화 발생 (크기가 달라 테트리스 실패) |
| 메모리 보호/공유 | 조각이 의미 없이 잘려 있어서 권한 주기가 조금 까다로움 | 함수 단위로 잘려 있어 Read-only 등 보안/공유 주기가 매우 쉬움 |
페이징의 뼈아픈 오버헤드 (Memory Access Penalty)
페이징은 외부 단편화를 해결한 대가로 '속도'라는 무서운 세금을 내야 한다.
- 용량 세금 (Page Table Size): 32비트 시스템에서 4KB 페이지를 쓰면, 페이지 장부(테이블) 하나당 4MB의 메모리를 먹는다. 100개 프로세스가 뜨면 장부 크기만 400MB의 램을 파먹는다.
- 속도 세금 (2번 읽기): CPU가 데이터를 원할 때, 메모리에 있는 '페이지 테이블'을 읽으러 한 번 가고, 알아낸 주소로 '실제 데이터'를 읽으러 메모리에 또 한 번 가야 한다. 메모리 접근 시간이 정확히 2배로 느려졌다.
┌──────────┬────────────┬────────────┬─────────────────────────────────────┐
│ 기법 │ 단편화 해결 │ 추가되는 낭비 │ 속도 지연 극복법 │
├──────────┼────────────┼────────────┼─────────────────────────────────────┤
│ 가변 분할 │ 해결 불가 │ 외부단편화(큼) │ (지연 없음) │
│ 페이징 │ 외부 완벽해결│ 내부단편화(작음)│ **TLB 캐시 하드웨어** 도입 │
└──────────┴────────────┴────────────┴─────────────────────────────────────┘
[매트릭스 해설] 컴퓨터 공학에서 '공짜 점심'은 없다. 공간적 유연성(비연속 할당)을 얻은 대가로 메모리 접근 속도가 2배로 느려지는 치명상을 입었다. 인류는 이 페이징의 느린 속도를 구원하기 위해 MMU 안에 초고속 하드웨어 캐시인 TLB(Translation Look-aside Buffer)를 긴급히 투입하여, 99%의 확률로 테이블을 안 읽고 바로 주소를 찾아가게 만듦으로써 페이징 아키텍처를 완성시켰다.
- 📢 섹션 요약 비유: 페이징은 책에 '찾아보기(색인)'를 만든 것과 같습니다. 지식이 어지럽게 흩어져 있어도 색인만 보면 다 찾을 수 있지만, 매번 뒷장의 색인표(페이지 테이블)를 펼쳤다가 다시 본문으로 돌아가야 하므로 독서 속도가 2배로 느려지는 딜레마를 낳았습니다.
Ⅳ. 실무 적용 및 기술사적 판단 (Strategy & Decision)
실무 시나리오: 카카오톡 복제 실행과 Shared Pages (공유 페이지)
페이징 기법의 진정한 숨은 마법은 '공유(Sharing)'에 있다.
- 상황: 회사 PC에서 크롬(Chrome) 브라우저 탭을 50개 띄우거나 별도 창을 5개 켰다.
- 연속 할당 시절: 크롬 실행 코드가 100MB라면, 5번 실행했으니 메모리에 500MB가 올라가야 했다.
- 페이징의 공유 흑마법:
- 크롬의 코드 부분(읽기 전용, 재진입 가능 코드 - Reentrant Code) 100MB는 물리 램(프레임)에 딱 1번만 올라간다.
- 실행된 5개의 크롬 프로세스는 각자 자신의 페이지 테이블을 갖지만, 이 테이블들이 모두 똑같은 물리 프레임 주소를 가리키도록 세팅된다.
- 사용자 각자의 입력 데이터나 탭 정보(Data 영역) 페이지만 물리 램에 별도로 분리되어 매핑된다.
- 결과: 메모리 사용량이 500MB에서 110MB 수준으로 극적으로 줄어든다. 이 페이지 단위의 유연한 매핑이 없었다면 현대 OS의 다중 창/다중 탭 구조는 메모리 폭발로 성립조차 할 수 없었을 것이다.
OOM (Out Of Memory) 상황의 체감 변화
과거 가변 분할에서는 램이 1GB가 남아도 10MB 앱이 실행 안 되는 억울한 에러를 뱉었다면, 페이징 시스템을 쓰는 현대 리눅스에서는 램의 마지막 4KB 프레임 1장까지 영혼까지 끌어모아 탈탈 털어 쓴다. 즉 현대 OS에서 OOM 에러가 발생했다는 것은 파편화 때문이 아니라 "진짜 물리 램의 잔고가 0원"이라는 가장 정직한 사망 선고다.
- 📢 섹션 요약 비유: 영화관에 5명의 친구가 갔을 때 팝콘 5개를 다 따로 사는 게 아니라, 초대형 팝콘 1통(공유 페이지)을 한가운데 물리적으로 두고 각자의 손(페이지 테이블 매핑)만 뻗어서 같이 먹어 식비를 극단적으로 절약하는 원리입니다.
Ⅴ. 기대효과 및 결론 (Future & Standard)
정량/정성 기대효과
| 구분 | 내용 |
|---|---|
| 외부 단편화 0% | 연속 공간 강박을 깨부숨으로써 악성 파편화를 원천 차단하고 압축(Compaction) 오버헤드 완전 제거 |
| 메모리 재활용 극대화 | 남은 빈 프레임이 1개라도 있으면 그 어떤 프로세스의 페이지 조각이라도 즉시 할당 가능 |
| 가상 메모리의 기초 | 프로세스 전체가 메모리에 없어도, 필요한 '페이지' 몇 장만 디스크(Swap)에서 가져와 실행하는 요구 페이징(Demand Paging)의 뼈대 제공 |
결론 및 미래 전망
페이징 (Paging)은 인류가 물리 메모리라는 딱딱한 하드웨어의 한계를 소프트웨어적 딕셔너리(매핑 테이블)와 가상화(Virtualization)의 마법으로 완전히 정복한 컴퓨터 공학의 절대적 승리다. 비록 테이블 참조 속도 지연과 장부 크기의 비대화라는 부작용을 낳았지만, 이를 TLB(캐시)와 다단계 페이징(Hierarchical Paging)이라는 하드웨어/소프트웨어 융합 기술로 찍어 누르며 현대 OS의 유일신이 되었다. 훗날 CXL(Compute Express Link) 같은 기술로 원격 서버의 램을 내 램처럼 쓰는 시대가 오더라도, 그 데이터를 자르고 매핑하는 기본 단위는 영원히 이 '페이지(Page)'라는 규격 안에서 이루어질 것이다.
- 📢 섹션 요약 비유: 덩치 큰 책(연속 할당)을 어떻게 책장에 구겨 넣을지 평생 고민하던 사서가, 아예 모든 책을 4KB짜리 동일한 두께의 링바인더(페이징)로 갈아 끼워버린 뒤부터는 아무 빈칸에나 눈 감고 꽂아도 되는 평화를 얻은 것입니다.
📌 관련 개념 맵 (Knowledge Graph)
- 외부 단편화 (External Fragmentation) | 페이징 아키텍처가 세상에 등장하게 된 결정적 원흉이자 가변 분할의 저주
- 페이지 테이블 (Page Table) | 찢어진 논리 페이지가 실제 물리 프레임 어디에 박혀있는지 알려주는 OS의 핵심 번역 장부
- 프레임 (Frame) | 물리 메모리(RAM)를 페이지와 똑같은 크기(주로 4KB)로 일정하게 잘라놓은 고정된 상자
- TLB (Translation Look-aside Buffer) | 페이징 테이블을 메모리까지 가서 읽는 속도 지연을 막기 위해 칩셋 내부에 박아넣은 초고속 캐시
- 공유 페이지 (Shared Pages) | 똑같은 프로그램(예: 크롬)을 여러 개 띄울 때 코드를 램에 1번만 올리고 테이블 매핑만 여러 번 해주는 절약 기법
👶 어린이를 위한 3줄 비유 설명
- 페이징이 무엇인가요? 커다란 로봇 장난감을 통째로 보관상자에 넣는 게 아니라, 팔, 다리, 몸통을 다 똑같은 크기의 작은 레고 블록으로 분해해서 서랍장 빈 곳 아무 데나 쏙쏙 나눠서 보관하는 방법이에요.
- 왜 그렇게 분해해서 넣나요? 서랍에 커다란 빈 공간이 없어도, 작은 레고 블록 단위로 쪼개면 남는 자투리 공간 하나 버리지 않고 100% 꽉꽉 채워 넣을 수 있으니까요. (외부 단편화 해결)
- 나중에 어떻게 갖고 놀아요? 운영체제라는 똑똑한 로봇이 "머리는 3번 서랍, 팔은 7번 서랍..."이라고 비밀 지도(페이지 테이블)에 다 적어둬서, 놀 때마다 1초 만에 조립해 준답니다.