1. 가상 메모리
가상 메모리(Virtual Memory)는 물리 메모리(RAM)의 크기보다 더 큰 프로그램을 실행할 수 있도록 지원하고, 각 프로세스에 독립적이고 연속적인 메모리 공간을 제공하는 운영체제의 핵심 기법입니다. 한정된 메모리 자원을 여러 프로세스가 효율적으로 나누어 사용하고, 서로를 보호하며, 물리 메모리 크기보다 더 큰 프로그램을 실행하기 위한 해결책입니다.
가상 메모리의 목적
- 물리 메모리 크기 제약 극복: 프로그램 전체가 메모리에 올라오지 않아도 실행이 가능하게 하여, 실제 RAM 크기보다 큰 프로그램을 실행할 수 있습니다.
- 메모리 보호 (Memory Protection): 각 프로세스는 자신만의 독립된 가상 주소 공간을 가지므로, 다른 프로세스의 메모리 영역을 침범할 수 없습니다. 이는 시스템의 안정성을 크게 향상시킵니다.
- 효율적인 메모리 관리: 여러 프로세스가 공통으로 사용하는 코드(e.g., 공유 라이브러리)를 물리 메모리에 한 번만 적재하고, 각 프로세스의 가상 주소 공간에 매핑하여 메모리를 절약할 수 있습니다.
2. 핵심 개념
- 가상 주소 공간 (Virtual Address Space): 프로세스가 참조하는 논리적인 주소 공간입니다. 32비트 시스템에서는 4GB(2^32), 64비트 시스템에서는 매우 큰(2^64) 크기를 가집니다. 각 프로세스마다 독립적으로 존재합니다.
- 물리 주소 공간 (Physical Address Space): 실제 메인 메모리(RAM)의 주소 공간입니다.
- 주소 변환 (Address Translation): CPU가 생성한 가상 주소(Virtual Address)를 실제 데이터가 저장된 물리 주소(Physical Address)로 변환하는 과정입니다. 이 과정은 하드웨어인 MMU(Memory Management Unit)가 담당합니다.
3. 주요 가상 메모리 기법
가상 주소 공간을 관리하고 물리 주소 공간에 매핑하는 방식에 따라 크게 페이징, 세그멘테이션으로 나뉩니다.
가. 페이징 (Paging)
- 개념: 가상 주소 공간과 물리 주소 공간을 각각 동일한 크기의 작은 블록으로 나누어 관리하는 기법입니다.
- 가상 주소 공간의 블록: 페이지 (Page)
- 물리 주소 공간의 블록: 프레임 (Frame)
- 동작: 프로그램 실행 시, 필요한 페이지들만 물리 메모리의 비어있는 프레임에 불연속적으로 적재됩니다. 운영체제는 어떤 페이지가 어떤 프레임에 있는지 페이지 테이블(Page Table)을 통해 관리합니다.
- 주소 변환 과정:
- CPU가 가상 주소
(p, d)를 생성합니다. (p: 페이지 번호,d: 페이지 내 오프셋) - MMU는 페이지 테이블에서 페이지 번호
p에 해당하는 항목을 찾습니다. - 페이지 테이블 항목에서 프레임 번호
f를 얻습니다. - 물리 주소
(f, d)를 계산하여 메인 메모리에 접근합니다.
- CPU가 가상 주소
- 페이지 테이블 (Page Table): 각 프로세스마다 하나씩 존재하며, 가상 페이지와 물리 프레임 간의 매핑 정보, 그리고 유효 비트(Valid-Invalid bit), 접근 비트(Accessed bit), 수정 비트(Dirty bit) 등의 상태 정보를 담고 있습니다. 페이지 테이블은 메인 메모리에 저장됩니다.
- TLB (Translation Lookaside Buffer): 페이지 테이블이 메인 메모리에 있어 주소 변환 시 메모리 접근이 두 번 필요한 문제를 해결하기 위한 고속 하드웨어 캐시입니다. 최근에 사용된 페이지-프레임 매핑 정보를 저장하여 주소 변환 속도를 크게 향상시킵니다.
- 장점:
- 메모리를 동일 크기로 관리하므로 관리가 용이합니다.
- 외부 단편화(External Fragmentation) 문제가 발생하지 않습니다.
- 단점:
- 내부 단편화(Internal Fragmentation)가 발생할 수 있습니다. (프로세스가 페이지 크기의 배수가 아닐 경우 마지막 페이지에서 낭비 발생)
- 페이지 테이블의 크기가 매우 커질 수 있습니다. (이를 해결하기 위해 다단계 페이징, 역페이지 테이블 등의 기법 사용)
나. 세그멘테이션 (Segmentation)
- 개념: 가상 주소 공간을 논리적인 의미 단위의 가변 크기 블록인 세그먼트(Segment)로 나누어 관리합니다. (e.g., Code Segment, Data Segment, Stack Segment)
- 주소 변환 과정:
- CPU가 가상 주소
(s, d)를 생성합니다. (s: 세그먼트 번호,d: 세그먼트 내 오프셋) - MMU는 세그먼트 테이블에서 세그먼트 번호
s에 해당하는 항목을 찾습니다. - 세그먼트 테이블 항목에는 세그먼트의 시작 물리 주소(base)와 크기(limit)가 저장되어 있습니다.
- 먼저
d < limit인지 확인하여 세그먼트 범위를 벗어나는 접근인지 검사합니다. (메모리 보호) - 물리 주소
base + d를 계산하여 메인 메모리에 접근합니다.
- CPU가 가상 주소
- 장점:
- 논리적 단위로 메모리를 관리하므로 공유와 보호가 용이합니다. (e.g., 코드 세그먼트는 공유하고, 데이터 세그먼트는 보호)
- 단점:
- 가변 크기 세그먼트들이 메모리에 적재되고 해제되면서 중간중간에 사용하지 못하는 작은 빈 공간들이 생기는 외부 단편화(External Fragmentation) 문제가 발생합니다.
다. 페이징된 세그멘테이션 (Paged Segmentation)
- 세그멘테이션과 페이징의 장점을 결합한 기법입니다.
- 메모리를 먼저 논리적인 세그먼트로 나누고, 각 세그먼트를 다시 고정된 크기의 페이지로 나눕니다.
- 주소 변환 과정이 더 복잡해지지만, 세그멘테이션의 논리적 장점과 페이징의 단편화 문제 해결 능력을 모두 취할 수 있습니다.
4. 요구 페이징과 페이지 폴트 (Demand Paging & Page Fault)
요구 페이징(Demand Paging)은 가상 메모리 시스템의 핵심 동작 원리로, 프로세스의 모든 페이지를 미리 메모리에 올리는 대신, 실제로 필요할 때(요구될 때) 해당 페이지를 메모리로 가져오는 기법입니다.
- 페이지 폴트 (Page Fault): 프로세스가 접근하려는 페이지가 현재 물리 메모리에 없는 경우 발생하는 하드웨어 인터럽트(트랩)입니다. 이는 오류가 아니라, 가상 메모리 시스템의 정상적인 동작 과정입니다.
- 페이지 폴트 처리 순서:
- 트랩 발생: CPU가 접근하려는 페이지의 페이지 테이블 항목의 유효 비트(Valid bit)가 '0'(invalid)이면, MMU는 OS에 트랩을 겁니다.
- OS 인터럽트 핸들러 실행: OS는 페이지 폴트의 원인을 파악합니다. (유효하지 않은 주소 접근인지, 아니면 단순히 메모리에 없는 것인지)
- 페이지 로드:
a. 보조 기억장치(디스크)에서 해당 페이지의 위치를 찾습니다.
b. 물리 메모리에서 비어있는 프레임(Free frame)을 확보합니다. 만약 비어있는 프레임이 없다면, 페이지 교체 알고리즘을 사용하여 기존에 있던 페이지 중 하나를 디스크로 내보냅니다(Swap-out).
c. 요청된 페이지를 디스크에서 비어있는 프레임으로 읽어들입니다(Swap-in). - 페이지 테이블 갱신: 페이지가 메모리에 적재되면, 페이지 테이블의 해당 항목을 갱신합니다. (유효 비트를 '1'로, 프레임 번호 기록)
- 명령어 재시작: 페이지 폴트를 유발했던 명령어를 다시 실행합니다. 이제는 페이지가 메모리에 있으므로 정상적으로 주소 변환이 이루어집니다.
5. 페이지 교체 알고리즘 (Page Replacement Algorithms)
페이지 폴트가 발생했고 비어있는 프레임이 없을 때, 어떤 페이지를 메모리에서 내보낼지 결정하는 알고리즘입니다. 목표는 페이지 폴트 발생 횟수를 최소화하는 것입니다.
- FIFO (First-In, First-Out): 가장 먼저 메모리에 들어온 페이지를 먼저 교체합니다. 구현은 간단하지만, 자주 사용되는 페이지가 오래전에 들어왔다는 이유로 교체될 수 있어 비효율적일 수 있습니다.
- OPT (Optimal, 최적 교체): 앞으로 가장 오랫동안 사용되지 않을 페이지를 교체합니다. 페이지 폴트 횟수가 가장 적어 이상적이지만, 미래의 접근 패턴을 예측할 수 없으므로 실제 구현은 불가능합니다. 다른 알고리즘의 성능을 비교하기 위한 기준으로 사용됩니다.
- LRU (Least Recently Used): 가장 오랫동안 사용되지 않은 페이지를 교체합니다. "과거에 오랫동안 사용되지 않았다면, 미래에도 사용되지 않을 것이다"라는 가정에 기반하며, OPT의 좋은 근사치입니다. 하지만 모든 페이지의 최근 사용 시간을 기록해야 하므로 구현 비용이 높습니다.
- Clock Algorithm (Second-Chance Algorithm): LRU의 근사 구현체입니다. 각 페이지에 참조 비트(Reference bit)를 두고, 포인터가 원형 큐를 순회하며 참조 비트가 0인 페이지를 교체 대상으로 찾습니다. 참조 비트가 1이면 0으로 바꾸고 한 번의 기회를 더 줍니다.
6. 요약
가상 메모리는 실제 물리 메모리보다 큰 프로그램을 실행하고 각 프로세스를 격리 보호하기 위한 핵심적인 운영체제 기법입니다. 프로세스는 자신만의 크고 연속적인 가상 주소 공간을 갖는 것처럼 동작하지만, 실제로는 '페이징' 기법을 통해 필요한 부분(페이지)만 물리 메모리(프레임)에 불연속적으로 적재됩니다. CPU가 요청한 가상 주소가 물리 메모리에 없으면 '페이지 폴트'라는 인터럽트가 발생하고, 운영체제는 해당 페이지를 보조 기억장치에서 가져와 적재합니다. 이 과정을 통해 물리 메모리의 한계를 극복하고 효율적인 다중 프로그래밍 환경을 제공합니다.
가상 메모리가 왜 필요한가
가상 메모리는 세 가지 주요 목적을 가집니다. 첫째, 실제 물리 메모리(RAM) 크기보다 더 큰 프로그램을 실행할 수 있게 해줍니다. 둘째, 각 프로세스에 독립적인 주소 공간을 제공하여 다른 프로세스의 메모리를 침범하지 못하도록 보호합니다. 셋째, 여러 프로세스가 라이브러리와 같은 공통된 코드를 메모리상에서 공유할 수 있게 하여 물리 메모리를 절약합니다.
페이징과 세그멘테이션의 차이점
페이징과 세그멘테이션은 모두 가상 주소 공간을 관리하는 기법이지만, 메모리를 나누는 방식에서 근본적인 차이가 있습니다. 페이징은 메모리를 '물리적인' 고정 크기 블록인 '페이지'로 나눕니다. 이 방식은 메모리 관리가 단순하고 외부 단편화가 발생하지 않는 장점이 있습니다. 반면, 세그멘테이션은 메모리를 '논리적인' 가변 크기 블록인 '세그먼트'(예: 코드, 데이터, 스택)로 나눕니다. 이는 공유와 보호에 유리하지만, 메모리 할당과 해제가 반복되면서 외부 단편화 문제가 발생할 수 있습니다.
페이지 폴트(Page Fault)란 무엇이며, 운영체제는 이를 어떻게 처리하나
페이지 폴트는 프로세스가 접근하려는 데이터가 담긴 페이지가 현재 물리 메모리에 없을 때 발생하는 하드웨어 인터럽트입니다. 처리 과정은 다음과 같습니다.
1) MMU가 OS에 트랩을 걸어 제어권을 넘깁니다.
2) OS는 해당 페이지를 디스크에서 찾습니다.
3) 물리 메모리에 비어있는 프레임을 확보하고, 없다면 페이지 교체 알고리즘으로 희생될 프레임을 결정합니다.
4) 해당 페이지를 디스크에서 메모리로 읽어들입니다.
5) 페이지 테이블을 갱신하여 새로운 매핑 정보를 기록합니다.
6) 마지막으로 원래 명령어를 다시 실행하여 작업을 재개합니다.
페이지 교체 알고리즘 중 LRU
LRU(Least Recently Used)는 '가장 오랫동안 사용되지 않은 페이지'를 교체 대상으로 선택하는 알고리즘입니다. 이는 '최근에 사용되지 않은 페이지는 앞으로도 사용되지 않을 가능성이 높다'는 시간적 지역성에 기반한 전략입니다. 최적(OPT) 알고리즘의 좋은 근사치로 알려져 성능이 우수하지만, 모든 페이지의 마지막 접근 시간을 추적해야 하므로 완벽한 구현은 비용이 많이 듭니다. 이 때문에 실제 시스템에서는 참조 비트를 사용하는 Clock 알고리즘과 같은 근사 구현을 주로 사용합니다.
'Computer Science' 카테고리의 다른 글
| 캐시 메모리 Cache Memory (0) | 2025.11.19 |
|---|---|
| CPU (0) | 2025.11.19 |
| 메모리 구조 (0) | 2025.11.17 |
| 깊은 복사와 얕은 복사 (0) | 2025.11.14 |
| Red-Black 트리 (0) | 2025.11.13 |
