우리가 사용하는 프로그램은 생각보다 훨씬 많은 메모리를 필요로 합니다. 그런데 물리적인 RAM은 한정되어 있지요. 이럴 때 운영체제가 사용하는 똑똑한 방법이 바로 *가상 메모리(Virtual Memory)*입니다.
이번 글에서는 가상 메모리의 개념부터, 어떻게 페이지를 가져오고 바꾸는지, 그리고 자주 헷갈리는 '쓰기 시 복사(Copy-on-Write)'까지 아이도 이해할 수 있도록 차근차근 풀어보겠습니다.
가상 메모리
는 실제 메모리보다 큰 주소 공간을 만들어내는 운영체제의 기술입니다. 프로그램 입장에서는 엄청나게 큰 메모리를 가진 것처럼 행동할 수 있지만, 실제로는 일부만 메모리에 있고 나머지는 디스크에 저장되어 있습니다.
예를 들어, 작은 방에 살면서 창고를 따로 두고 필요한 짐만 꺼내놓는 것과 비슷해요.
메모리가 부족해도 많은 프로그램을 동시에 실행할 수 있어요.
실제 메모리보다 훨씬 넓은 공간을 흉내 낼 수 있어요.
프로세스끼리 서로의 메모리를 침범하지 않도록 보호할 수 있어요.
🚀
요구 페이징 (Demand Paging) 🔗
가상 메모리는 처음부터 모든 페이지를 메모리에 올려두지 않고,
필요할 때만
불러오는 방식을 사용합니다. 이것을
요구 페이징(Demand Paging)
이라고 합니다.
📦 꼭 필요한 물건만 창고에서 꺼내 쓰는 것과 같아요.
프로그램 실행 → 필요한 첫 몇 페이지만 메모리에 적재
실행 중 다른 페이지가 필요 → 페이지 폴트(Page Fault)
발생
디스크에서 해당 페이지를 불러옴 → 메모리에 적재
다시 실행 계속
프로세스가 10개의 페이지를 가지고 있지만, 메모리에는 3개만 올림
나머지 페이지가 필요해지면 운영체제가 "페이지 폴트!"를 감지
필요한 페이지를 디스크에서 RAM으로 복사
요구 페이징 덕분에 메모리를 더 넓게 쓸 수 있습니다.
🚀
페이지 교체 (Page Replacement) 🔗
문제는 메모리가 꽉 찼을 때입니다. 새 페이지를 메모리에 넣어야 하는데, 이미 가득 차 있다면 어떻게 해야 할까요?
🎒 가방에 책이 너무 많으면, 안 읽는 책을 꺼내고 새 책을 넣는 것과 같아요.
이럴 때 운영체제는
페이지 교체 알고리즘
을 사용하여 어떤 페이지를 내보낼지 결정합니다.
대표적인 알고리즘은 다음과 같습니다.
가장 먼저 들어온 페이지부터 제거합니다.
페이지 프레임: 3개
요청: A, B, C, A, D
→ 적재 순서: A, B, C
→ A는 재사용됨
→ D 요청 시, A가 가장 먼저 들어왔으므로 A 제거
→ 페이지 교체: A → D
가장 오랫동안 사용하지 않은 페이지를 제거합니다.
페이지 프레임: 3개
요청: A, B, C, A, D
→ A, B, C 적재
→ A 재사용됨 → A는 최근 사용됨
→ D 요청 → B가 가장 오래 사용되지 않음 → B 제거
→ 페이지 교체: B → D
앞으로 가장 늦게 사용될 페이지를 제거 (미래를 알아야 해서 실제로는 사용 어려움)
페이지 프레임: 3개
요청: A, B, C, A, D, B
→ A, B, C 적재
→ A 재사용됨
→ D 요청 → C는 앞으로 사용되지 않음 → C 제거
→ B 요청 → A는 안 쓰고 D는 나중에 → D 제거 (미래 기준)
🚀
쓰기 시 복사 (Copy-on-Write) 🔗
두 개의 프로세스가 같은 데이터를 사용할 때, 처음에는 똑같은 페이지를
공유
하다가
한쪽이 수정하려고 할 때만 복사
하는 기법입니다.
📄 복사한 문서를 읽기만 하면 같이 보지만, 누가 수정하려 하면 따로 복사본을 만드는 것과 같아요.
부모 프로세스가 자식 프로세스를 만들면서 메모리 공유
둘 다 메모리 읽기 가능
한쪽이 데이터를 수정하려 하면 → 해당 페이지만 복사해서 분리
이 기법은
fork()
이후 효율적인 메모리 관리를 위해 매우 자주 사용됩니다.
🚀
메모리 압축 (Memory Compression) 🔗
일부 운영체제는 스와핑 대신, 사용하지 않는 데이터를
압축해서 메모리에 더 많은 데이터를 유지
하기도 합니다.
macOS, 일부 리눅스 배포판 등에서 사용
압축률이 높고 CPU 여유가 있을 때 효과적
가상 메모리는 사용자 프로그램뿐 아니라 커널 영역도 활용합니다.
운영체제 내부에서도 메모리를 요청하고 해제해야 하므로, 커널은 자체적인 메모리 할당자(slab, buddy 등)를 갖고 있습니다.
커널은 '운영체제 안의 작은 프로그램'이라고 생각하면 됩니다. 이 프로그램도 메모리가 필요해요!
이번 글에서는 가상 메모리의 핵심 개념과 함께, 요구 페이징, 페이지 교체, 쓰기 시 복사 등 실제 운영체제가 어떻게 메모리를 효율적으로 사용하는지를 살펴보았습니다.
다음 글에서는 대용량 저장장치 구조와 디스크 스케줄링에 대해 알아보겠습니다.