가상 메모리(Virtual Memory)는 물리적 메모리를 추상화하는 개념으로 보다 고차원적인 메모리 관리를 가능케 하는 기술이다.
이 기술을 사용하면 메모리 추상화 자체에서 얻을 수 있는 이점에 더하여, 물리적인 메모리 공간보다 더 많은 가상의 메모리 공간을 설정하여 메모리를 관리할 수 있다는 추가적인 이점이 생긴다.
가상 메모리 기술은 페이징이나 세그멘테이션 방법을 통해 구현되는데, x86-64에서는 가변 길이의 메모리 블럭을 사용하는 세그멘테이션보다는 고정 길이의 메모리 블럭을 사용하는 페이징이 선호된다. [링크]
이 글에선 페이징만을 설명할 예정이다.
우선 페이징이 무엇인지를 먼저 살펴보자.
페이징 방법은 메모리를 페이지(Page)라는 고정 크기 형태로 블럭화하여 운용한다.
페이지의 총 크기는 곧 가상 메모리 공간의 크기가 되는데, 만약 이 크기가 물리 메모리 공간보다 클 경우 그 여분은 보조기억장치(하드디스크 등)에 저장된다. [RHEL]
이 때 물리 메모리와 보조기억장치 간 페이지를 정책에 따라 교환(스왑)하는 것을 페이징이라 한다.
그렇다면 만약 물리 메모리에 CPU가 요청한 페이지가 없다면 어떻게 될까?
이것이 페이지 폴트이다.
이 경우 스왑 영역(보조기억장치에 위치한 가상 메모리 영역)에서 페이지를 찾아 물리 메모리에 로드한다.
페이지 폴트는 그 원인에 따라 세 가지로 분류된다.
Major Page Fault
Major 페이지 폴트는 일반적으로 스와핑으로 알려진 동작을 의미한다.
요청한 페이지가 물리 메모리로부터 스왑아웃(Swap-Out)되어 보조기억장치의 가상 메모리에 저장되어있다면 해당 페이지를 다시 물리 메모리로 스왑인(Swap-In)하여야 할 것이다.
이것을 Major 페이지 폴트라 한다.
Major 페이지 폴트는 Disk I/O를 발생시킨다.
Minor Page Fault
요청한 페이지가 물리 메모리에는 로드되었지만 메모리 관리 유닛(Memory Management Unit, MMU)에는 로드되어있지 않다고 표시된 경우 이를 Minor 페이지 폴트라 한다.
설명이 좀 복잡하지만, 어느 프로세스의 한 쓰레드가 어떤 페이지를 사용하고 있을 때 해당 프로세스의 다른 쓰레드가 그 페이지를 요청하는 경우를 예시로 들 수 있다.
이 경우, MMU는 해당 쓰레드에서 요청한 페이지가 이미 사용되고 있는 페이지를 가리키도록 하면 되기 때문에 스왑인이 발생하지 않는다. (다시말해 Disk I/O가 생기지 않는다)
Invalid Page Fault
흔한 블루 스크린 원인이다.
요청한 페이지가 스왑영역의 밖을 참조하거나, 페이지를 쓰기 불가능한 영역에 쓰려고할 때 발생하는 페이지 폴트이다.
이 경우에는 페이지 폴트 핸들러가 세그멘테이션 폴트(Segmentation Fault)를 발생시킨다.
결과는 보통 커널 패닉(블루 스크린)으로 나타난다.
Page Replacement Algorithm
페이지 교체 알고리즘은 다양하다.
흔히 언급되는 것들은 다음과 같다.
- FIFO (First In First Out)
- Optimal
- LRU (Least Recently Used)
- LFU (Least Frequently Used)
- MFU (Most Frequently Used)
굳이 설명해야하나 싶을 정도로 네이밍을 잘 해놨다.
아무래도 가장 많이 사용되는 것은 LRU이다.
직관적으로도 가장 잘 될 것 같다.
가장 오랫동안 안쓰인 페이지를 교체하는 알고리즘이다.
이 외에도 많은 페이지 교체 알고리즘들이 있으며 아직도 연구되는 중이다.
이외의 이야기는 상당히 지엽적이라 링크로 대체한다.
이야기를 컴퓨터 구조론적으로 풀어낸 좋은 글이다.