멈추지 않고 끈질기게

[컴퓨터 공학] 가상 메모리(virtual memory) 본문

컴퓨터공학

[컴퓨터 공학] 가상 메모리(virtual memory)

sam0308 2023. 2. 10. 11:51

※ 해당 포스팅은 개인의 공부 정리용 글입니다. 틀린 내용이 있다면 추후 수정될 수 있습니다.

 

 

이번 포스팅에서는 가상 메모리에 관하여 알아보겠습니다.

 

1. 가상 메모리의 정의

 가상 메모리(virtual memory)란 프로세스에 실제 사용하는 물리적인 메모리가 아닌 추상화된 가상의 메모리를 할당하여 실제 메모리 크기보다 더 크게 사용할 수 있게 하는 기술입니다. 가상 메모리상에서의 주소를 가상 주소(virtual address) 또는 논리 주소(logic address)라고 하며, 이와 구분하기 위해 실제 물리 메모리의 주소는 물리 주소(physical address) 또는 실 주소 라고 합니다. 프로세스는 가상 주소를 할당 받아 실행되고, 가상 주소는 메모리 관리 장치(MMU / Memory Management Unit)에 의해 물리 주소로 변환됩니다.

 

그림 1. 가상 메모리

 

2. 페이징(paging)

 페이징이란 가상 주소 공간은 페이지(page), 물리 주소 공간은 프레임(frame)이라는 단위 유닛으로 자르고 페이지에 프레임을 할당하는 기법입니다. 간단하게 말하자면 메모리를 잘게 쪼개서 이용하는 방법이며, 이 때 페이지와 프레임의 크기는 같아야 합니다. 페이징 방식을 쓰는 이유를 이해하려면 우선 외부 단편화(external fragmentation)에 대해 알아야 합니다.

 

그림 2. 외부 단편화(external fragmentation)

 상기 도식처럼 500MB 크기의 메모리에 100MB짜리 프로세스 두개가 실려있다고 가정해봅시다. 남은 공간은 총 300MB입니다. 그렇다면 이 메모리에 300MB짜리 프로세스를 추가로 실을 수 있을까요? 물론 불가능합니다. 남은 공간은 300MB이지만, 프로세스 두 개에 의해 공간들이 분리되어 실제로는 절반인 150MB짜리 프로세스조차 적재할 수 없습니다. 이렇게 프로세스들에 의해 메모리 공간이 작게 분리되어 메모리가 낭비되는 현상외부 단편화라고 합니다.

 페이징 기법을 사용하면 이와 같은 문제를 해결할 수 있습니다. 프로세스를 페이지 단위로 적재하기 때문에 위와 같이 메모리 공간이 분리되어 있어도 불연속적으로 프로세스를 적재할 수 있고, 외부 단편화를 해결함으로써 메모리 효율이 증가하게 됩니다.

 

그림 3. 페이징(paging)

 

 또한 메모리 할당 기법에는 현재 실행되지 않는 프로세스는 메모리 상에서 보조기억장치에 잠시 옮겨두고(swap-out), 빈 공간에 새로운 프로세스를 적재하여(swap-in) 실행하는 스와핑(swaping)이라는 개념이 있습니다. 페이징 기법에서는 스와핑 또한 페이지 단위로 이루어집니다(page-out / page-in). 이는 곧 프로세스 전체를 메모리에 적재하지 않고 실행할 수 있다는 뜻입니다. 처음 실행에 필요한 페이지들만 적재하고, 나머지는 필요할 경우 페이지 인/아웃 하는 식으로 프로세스를 실행할 수 있습니다.

 

 

3. 페이지 테이블(page table)

 다만 페이징 기법으로 메모리에 프로세스를 불연속적으로 적재할 경우, CPU가 명령어의 주소를 찾기 어려워지는 문제점이 있습니다. 이를 해결하기 위해 페이지 테이블(page table)을 사용합니다. 페이지 테이블은 페이지와 프레임을 짝지어놓은 테이블로, 프로세스마다 이러한 테이블을 가지며 이를 통해 해당 페이지에 할당된 프레임의 위치를 찾을 수 있게 해줍니다. 논리 주소 상에서는 프로세스들을 연속적으로 배치하고 불연속적으로 적재된 실제 물리 주소에는 페이지 테이블을 통하여 접근하게 함으로써, CPU가 다음 명령어를 쉽게 찾을 수 있게 됩니다.

 

그림 4. 페이지 테이블(page table)

 

 

4. 페이지 폴트(page fault)와 페이지 교체 알고리즘

 프로세스 전체를 메모리에 적재하지 않기 때문에, 프로세스 실행 중 필요한 페이지가 메모리에 적재되지 않은 경우가 발생하게 되며 이를 페이지 폴트(page fault)라고 합니다. 페이지 폴트가 발생할 경우 기존의 페이지를 내보내고 필요한 페이지를 메모리에 적재하는 교체 과정을 거쳐야 하며, 이는 물론 시간을 소모하므로 페이지 폴트가 자주 발생할수록 성능이 하락하게 됩니다. 따라서 페이지 폴트 빈도를 줄이기 위해 다양한 페이지 교체 알고리즘이 존재합니다.

 

 최적(Optimal) 페이지 교체 알고리즘은 가장 이상적인 페이지 교체 알고리즘입니다. 앞으로 사용될 빈도가 가장 낮은 페이지를 교체하여 페이지 폴트 빈도를 최소한으로 만드는 방식입니다. 다만, 이 알고리즘은 사실상 이론상의 알고리즘입니다. 프로세스가 앞으로 어떤 페이지를 참조할지를 미리 예측해야 하는데, 이는 매우 어려운 일이기 때문입니다. 따라서 이론상의 최고 성능을 측정하고, 이를 기준으로 다른 교체 알고리즘을 평가하는 데에 사용됩니다.

 

 FIFO(First-In First -Out) 페이지 교체 알고리즘은 이름에서 알 수 있듯이 가장 먼저 메모리에 적재했던 페이지부터 교체하는 방식입니다. 구현 난이도가 낮다는 장점이 있지만, 반대로 성능은 보장하기 힘듭니다. 계속 접근해야 하는 페이지조차 순서가 되면 교체해 버리기에 페이지 폴트 빈도가 높기 때문입니다.

 

 LRU(Least-Recently Used) 페이지 교체 알고리즘은 최적 페이지 교체 알고리즘 만큼은 아니여도, 어느정도 페이지의 사용 빈도를 참조하여 교체함으로서 페이지 폴트 빈도를 줄이는 알고리즘입니다. 미래를 예측하는 것은 어렵기에 대신 과거를 참조하여, 이름 그대로 최근에 가장 적게 사용된 페이지를 교체하는 방식입니다. Optimal 보다는 현실적으로 구현할 수 있고, FIFO 같은 단순 알고리즘 보다는 낮은 페이지 폴트 빈도를 보장하는 알고리즘으로 실제로도 가장 많이 쓰인다고 합니다.

 

이 밖에도 LFU(Least-Frequently Used ), MFU(Most-Frequently Used), Second Chance 등 다양한 페이지 교체 알고리즘이 존재하며, 이에 대해서는 추후에 좀 더 공부하고 나서 다루도록 하겠습니다.