운영체제 | 가상메모리 | 페이징 관련 키워드 정리
익명 페이지와 file-backed 페이지
가상 메모리 시스템에 할당된 페이지를 분류할 때, 대부분의 경우 이들을 'anonymous 페이지'와 'file-backed 페이지'로 나눌 수 있다. 익명 페이지는 '새로운 것'을 만들기 위한 빈 페이지라고 생각할 수 있고, 파일 기반 페이지는 '이미 존재하는 것'을 보기 위한 페이지라고 생각할 수 있다.
익명 페이지 (Anonymous Pages)
- Anonymous 페이지는 특정 파일에 직접 매핑되지 않는 메모리 페이지이다.
- 프로세스의 동적 메모리 할당(예: malloc을 사용한 메모리 할당, 스택 공간)에 주로 사용된다.
- 시스템이 메모리 부족 상황에 처했을 때, 이러한 페이지는 스왑 공간(디스크)으로 옮겨질 수 있다.
익명 페이지들은 임시 데이터를 저장하는 데 사용되며, 런타임 동안만 존재한다. 이 페이지들은 프로그램이 '새로운 것'을 만들고 싶을 때 사용된다. 컴퓨터 입장에서 빈 A4 용지와 같다고 생각하면 된다. 예를 들면, 프로그램이 계산을 위해 잠시 사용하는 메모리 공간은 익명 페이지일 수 있다. 또는 게임에서 새로운 레벨이 시작될 때 필요한 공간이 이에 해당한다. 이 공간은 파일 시스템에 있는 특정 파일과 직접 연결되어 있지 않다. 이런 페이지들은 아무 파일과도 연결되어 있지 않기 때문에 '익명'이라고 불린다.
파일 기반 페이지 (File-backed Pages)
- File-backed 페이지는 파일 시스템 내의 파일에 직접 매핑되는 메모리 페이지이다.
- 실행 파일, 라이브러리, 메모리 매핑된 파일의 내용 등을 메모리에 로드할 때 사용된다.
- Page fault 발생 시, 운영체제는 해당 파일의 내용을 읽어 해당 페이지를 메모리로 로드한다.
이번에는 책을 생각해보자. 책에는 이미 많은 내용이 적혀 있고, 우리는 책을 읽으면서 그 내용을 따라간다. 컴퓨터에게 file-backed page는 책에 비유할 수 있다. 이 페이지들은 이미 존재하는 파일들(ex. 문서, 사진, 프로그램 등)과 연결되어 있다. 컴퓨터가 이 파일들을 사용할 때, 이 파일들은 메모리에 로드되어 파일 기반 페이지가 된다. 그 전에는 페이지로 영역이 정해지지 않은, 디스크에 존재하는 바이너리 데이터일 뿐이다.
'프레임'이란 용어에 대해서
디스크에 스왑 아웃된 페이지는 프레임이라고 부르지 않는다. "프레임"이라는 용어는 주로 메인메모리 내의 페이지에 할당된 공간을 가리키는 데 사용된다. 즉, 메인 메모리에 로드된 페이지가 저장되는 물리적인 메모리 단위를 프레임이라고 한다. 스왑 아웃된 페이지는 디스크의 스왑 공간에 저장되며, 이는 프레임과 다른 개념이다. 엄밀히 말하면 그저 디스크 기반의 바이너리 데이터로 취급된다.
프레임 정의는 다음 두가지만 기억하면 될 것 같다.
- 메인메모리의 단위: 프레임은 메인 메모리(RAM) 내의 고정된 크기의 블록이다.
- 페이지와의 매핑: 가상 메모리 시스템에서 각 페이지는 메모리의 프레임에 매핑되어 로드된다.
스왑 공간
- 스왑 공간은 디스크에 위치한 저장 공간으로, 메모리가 부족할 때 사용된다.
- 스왑 아웃: 메모리 부족 시, 일부 페이지는 메모리에서 디스크의 스왑 공간(스왑 파티션 또는 스왑 파일)으로 이동(스왑 아웃)된다. 이러한 페이지는 더 이상 프레임에 저장되지 않는다.
- 스왑 파티션: 하드디스크, SSD에 물리적으로 공간을 할당
- 스왑 파일: 파일의 형태로, 즉 소프트웨어적인 기법으로 스왑 공간의 역할을 수행함. 크기 조절, 삭제 등에 용이함. 그러나 파일 시스템 오버헤드 발생.
- 페이지 교체는 메모리에 공간이 아예 없을 때만 하는게 아니다. 메모리에는 항상 여유 공간을 둬야하기 때문에, 적절한 여유공간의 최솟값을 정해둔다. 이 최솟값보다 여유공간이 낮아지면 페이지 교체 메커니즘이 발동된다.
- 바이너리 데이터 형태: 메모리에서 디스크로 이동된 페이지는 바이너리 형태의 데이터로 저장된다. 이 데이터는 메모리에서 사용되었던 그대로의 형태로 디스크에 기록된다.
스왑 아웃된 페이지의 추적
- 페이지 테이블의 역할: 메모리에 있을 때 각 페이지는 페이지 테이블을 통해 특정 프레임에 매핑된다. 스왑 아웃되면, 페이지 테이블은 이 페이지가 더 이상 메모리에 존재하지 않음을 valid bit(= present bit)에 표시한다.
- 스왑 아웃된 페이지의 추적: 일부 운영체제는 페이지 테이블(또는 별도의 구조)을 사용하여 스왑 아웃된 페이지의 위치를 추적한다. 이는 페이지가 스왑 인(swap in, 즉 디스크에서 다시 메모리로 로드될 때) 되어야 할 때 필요하기 때문이다.
페이지 교체 정책
- FIFO: 말그대로 FIFO 정책
- 이 방법은 구현이 간단하지만, 사용 빈도가 높은 페이지가 교체될 가능성이 있어 효율적이지 않을 수 있다.
- LRU: 가장 오래전에 쓰인 페이지를 교체한다.
- 이 방식은 최근 사용된 페이지가 미래에도 사용될 가능성이 높다는 가정에 기초한다.
- LRU는 보다 효율적인 페이지 교체 방식을 제공하지만, 구현이 복잡할 수 있다.
- LFU: 가장 적게 쓰인 페이지를 교체한다.
- 이 방식은 사용 빈도가 가장 낮은 페이지를 찾아 교체하므로, 주로 장기간 동안 사용되지 않은 페이지가 교체 대상이 된다.
- LFU는 사용 빈도에 기반하여 교체 대상을 결정하지만, 최근의 사용 패턴 변화를 반영하지 못하는 단점이 있을 수 있다. (예를 들어, 새롭게 들어온 페이지는 앞으로 쓰일 빈도와 관계없이 희생자 페이지가 될 가능성이 크다.)
- 랜덤: 랜덤으로 희생자 페이지를 정한다.
- 이 방식은 구현이 매우 간단하며, 특정한 사용 패턴에 편향되지 않는 장점이 있다.
- 의외로 LRU에 근접한 성능을 보인다.
Dirty bit (Modified bit)
해당 페이지가 메모리에 로드된 이후에 수정되었는가? 여부이다. 수정되었다면 이를 다시 디스크에 fsync() 해야하기 때문에 비용이 더 큼. 따라서 해당 비트가 1로 설정되지 않은 깨끗한 페이지를 내보내는 것을 선호하는 경우가 많다.
요구페이징
예측해서 페이징하지 않고. 실제로 해당 페이지가 요구되면, 페이지폴트 일으킨 다음에 해당 페이지를 가져오는 것을 선호한다.
쓰래싱
사용되고 있는, 필요한 메모리가 정해진 메모리 공간보다 클 경우, 끊임없이 페이지 교체가 발생한다. 아무리 페이지 교체를 해도 또 교체가 필요할테니까.. 이러한 상황이 쓰래싱이다.