-
[OS] 가상 메모리(Virtual Memory)의 원리와 작동 방식CS/OS 2025. 9. 24. 17:26
운영체제의 핵심: Virtualization
운영체제는 컴퓨터의 핵심 부품들을 'Virtualization'해서 우리가 편하게 쓸 수 있도록 만들어준다. 여기서 Virtualization라는 건, 실제로는 하나뿐인 자원(예: CPU나 메모리)을 여러 개가 있는 것처럼 꾸며서 각 프로그램이 자기만의 전용 자원을 쓰는 것처럼 느끼게 해주는 기술이다.
지난번에 살펴온 Process, CPU Scheduling도 Virtualization을 위한 방법이었는데, 오늘은 Virtual Memory에 대해서 살펴보겠다.
Virtual Memory란?
"어떻게 운영체제가 하나의 물리적인 메모리를 가지고, 여러 프로그램이 마치 자신만의 크고 사적인 메모리 공간을 가진 것처럼 느끼게 만들 수 있을까?"라는 문제를 운영체제가 해결하기 위해 Virtual Memory가 등장하였다.메모리 가상화는 운영체제가 물리적인 메모리(physical memory)를 추상화해서 각 프로세스마다 가상의 메모리 공간을 제공하는 것을 말한다. 그래서 각 프로세스는 마치 자기가 메모리 전체를 혼자 쓰는 것처럼 illusion을 느끼게 된다.
이런 메모리 가상화 덕분에 다음과 같은 이익이 생긴다.- 프로그래밍이 쉬워진다. 개발자는 메모리 주소를 신경 쓸 필요 없이 편하게 코딩할 수 있다.
- 시간과 공간 측면에서 메모리 효율이 높아진다.
- 프로세스를 위한 isolation에서 이점이 있다. 한 프로세스가 다른 프로세스의 메모리를 침범해서 문제를 일으키는 것을 막아준다.
과거의 메모리 사용 방식과 현재의 사용 방식
과거의 운영체제는 메모리에 하나의 프로세스만 올리고 실행했다.
프로그램이 끝나면 메모리에서 내리고, 다음 프로그램을 올리는 방식이이다. 마치 한 사람이 거실을 혼자 쓰고 나면 다음 사람이 들어오는 것과 같다. 따라서 메모리 효율성과 활용성이 매우 저하됐다.
현재는 멀티 프로그래밍(Multiprogramming) 시대이다. 여러 프로세스를 동시에 메모리에 올려 사용한다. 운영체제는 짧은 시간 동안 한 프로세스를 실행하다가 다른 프로세스로 바꿔가며 실행한다. 덕분에 과거에 문제였던 CPU 활용도와 효율성이 엄청나게 개선되었다.

하지만 이때부터 Protection issue가 중요해졌다. 한 프로그램이 실수로 다른 프로그램의 메모리에 접근해서 오류를 발생시킬 수 있는 경우가 생기기 때문이다.
그래서 가상 메모리의 세 가지 주요 목표가 생겨났다.
- 투명성(Transparency): 프로그램은 자기가 전용 메모리를 쓰는 것처럼 느끼게 해야한다. (프로그램은 가상화가 되어있는 걸 모르게 숨겨야한다)
- 효율성(Efficiency): 가상화 과정이 너무 느리지않고 오버헤드가 발생하지 않아야한다. 뒤에서 설명하겠지만 하드웨어의 도움을 필요로 한다.
- 보호(Protection): 한 프로세스가 다른 프로세스와 운영체제를 침범하지 못하도록 막아야한다. Isolation을 통해서 한 프로그램이 다운되더라도 다른 프로그램은 다운되지 않도록 하는것이 중요하다.
Address Space
운영체제는 주소 공간(Address Space)이라는 개념을 통해 물리 메모리를 추상화(abstraction)한다. 주소 공간은 실행 중인 프로세스와 관련된 모든 것을 담고 있다.
일반적인 address space는 다음과 같이 구성된다.
- 코드(Code): 프로그램의 명령어들이 저장되는 곳.
- 힙(Heap): malloc이나 new 같은 명령어로 동적으로 메모리를 할당하는 공간.
- 스택(Stack): 함수 호출 시 사용되는 지역 변수나 매개 변수, 반환 주소 같은 것들이 저장되는 공간.

개발자가 코드를 짤 때 사용하는 주소는 모두 가상 주소(virtual address)이다. 운영체제는 이 가상 주소를 실제 물리 주소(physical address)로 변환해준다.
예를 들어, 아래와 같은 간단한 C코드를 실행해보자#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]){ printf("location of code : %p\n", (void *) main); printf("location of heap : %p\n", (void *) malloc(1)); int x = 3; printf("location of stack: %p\n", (void *) &x); return x; }
이 코드를 64비트 리눅스 머신에서 실행하면, 코드, 힙, 스택의 주소가 각각 0x40057d, 0xcf2010, 0x7ff9ca45fc처럼 전혀 다른 주소로 출력된다. 이게 바로 가상 주소의 예시이다.
가상 메모리의 작동 원리
즉, 메모리 가상화는 각각의 process가 주소를 0부터 시작하는 것 처럼(프로세스가 메모리를 독점하는 것처럼) 생각한다. 실제로 프로그램은 물리 주소에서 실행되고 있는데 말이다.
메모리 가상화는 가상 주소를 물리 주소로 변환하는 과정을 통해 이루어진다.
예: virtual address 0 -> physical address 320KB
이 변환 작업은 MMU(Memory Management Unit)라는 하드웨어가 담당한다. MMU는 CPU에서 나오는 가상 주소(virtual address)를 받아 물리 주소(physical address)로 바꿔준다. 이 MMU 덕분에 여러 프로세스가 안전하고 효율적으로 물리 메모리를 공유할 수 있다. 또한 어플리케이션은 물리 주소(physical address)를 보지 않아도 되는 것이다.
만약 프로그램이 접근해서는 안 되는 주소에 접근하려고 하면, MMU가 이를 감지하고 '오류 핸들러(fault handler)'로 신호를 보내서 프로그램을 중단시킨다. 이렇게 함으로써 다른 프로그램의 메모리를 보호한다.

가상 메모리는 운영체제가 하드웨어(MMU)의 도움을 받아 각 프로그램에 크고 독립적인 가상 주소 공간을 제공하는 것이고 , 이를 통해 각 프로그램은 마치 자신만의 전용 메모리를 사용하는 것처럼 실행될 수 있다.
- 프로그램은 Virtual addresses(가상 주소)에 저장/로드한다.
- 실제 메모리는 Physical addresses(물리 주소)를 사용한다.
- VM 하드웨어는 Memory Management Unit(MMU)이다.

정리
Virtual Memory(가상 메모리)는 각 프로그램에게 마치 크고, 텅 비어있고, 오직 자기만 쓰는 듯한 전용 메모리 공간을 제공하는 것 같은 기술이다.
이게 가능한 핵심은 바로 주소 변환(address translation)이다. 프로그램이 사용하는 가상 주소(virtual address)를 운영체제와 하드웨어의 도움을 받아 물리 주소(physical address)로 바꿔준다. 덕분에 여러 프로그램이 하나의 물리 메모리를 안전하고 효율적으로 공유할 수 있다.

출처: 경북대학교 한명균 교수님, “운영체제” 강의 자료
'CS > OS' 카테고리의 다른 글
[OS] Base & Bounds의 한계와 Segmentation의 등장 (0) 2025.10.06 [OS] 주소 변환(Address Translation)과 Base-and-Bounds (1) 2025.10.04 [OS] Priority Inversion부터 MLFQ까지: 스케줄링 문제와 해결책 (0) 2025.09.17 [OS] CPU 스케줄링의 원리와 알고리즘: FIFO, SJF, STCF, RR 비교와 I/O 통합 (0) 2025.09.15 [OS] Direct Execution과 Limited Direct Execution: CPU 가상화의 핵심 원리 (0) 2025.09.15