[CS] 가상메모리
가상메모리의 역할과 동작 방식
- 리눅스에서 하나의 프로세스에 할당하는 메모리는 4GB정도
- 하지만 통상 시스템 물리 메모리는 8GB~32GB 정도
- 프로세스당 할당된 메모리는 4GB이지만 프로세스가 실제로 동작할 때 참조하는 메모리는 제한적
- CPU가 실제로 프로세스에서 참조하는 공간만 물리 메모리에 할당할 수 있음
아이디어
- 프로세스는 가상메모리의 주소를 사용하고, 데이터를 읽거나 쓸 때 물리 주소로 변환하여 참조할 수 있다.
- 프로세스는 가상 주소를 먼저 참조하고 MMU에 의해 물리주소를 확인하여 물리 메모리에 접근할 수 있다
MMU (Memory Management Unit)
- CPU에서 가상 주소 메모리 접근이 필요할 때, 해당 가상주소를 물리주소로 변환해 주는 하드웨어
페이징
- 물리메모리에 할당된 가상메모리 공간의 효율적인 관리를 위해 페이지 단위의 크기를 동일하게 설정하여 관리함
- 하드웨어에서 지원에 따라 페이징 크기가 다름
- 인텔 x86 시스템에서는 4KB, 2MB, 1GB 단위로 지원
- 리눅스에서는 4KB로 페이징
- 해당 페이지 단위로 가상메모리를 구분하고 해당 단위만큼 물리메모리에 할당
- 각각에 프로세스의 PCB에는 가상주소와 물리주소의 매핑정보가 있는 Page Table 구조체를 가리키는 주소가 있음
- CPU에서 가상주소에 접근하면 가상주소가 포함된 페이지를 탐색 → 해당 페이지를 인덱스로 Page Table에서 접근하여 물리 메모리 주소를 받아와 해당 주소로 CPU에서 처리
구조
- Page(Page Frame) : 고정된 크기의 Block (보통 4KB)
- 가상주소 V는 두개의 영역으로 구분됨
- p : 가상 메모리의 페이지 주소 (기준) → 12~31비트
- d : 페이지 내에서 참조하는 위치 (오프셋) → 0~11비트
- p + d : 실제 물리주소
프로세스가 4GB를 사용하는 이유는 32bit 시스템 내에서 4GB이내의 모든 주소를 저장할 수 있기 때문
동작
- 프로세스에서 특정 가상 주소에 엑세스하기 위해서 다음의 단계를 진행
- 해당 프로세서의 Page Table에 가상 주소가 포함된 Page번호가 있는지 확인
- Page번호가 있다면 해당 Page번호가 매핑된 물리 메모리 주소를 알아냄 (p’)
- 해당 물리메모리 주소(p’) + 오프셋(d)를 계산하여 실제 물리 메모리 주소를 확인
- Page Table에 저장된 페이지에 Valid-Invalid Bit를 저장해서 물리메모리에 해당 페이지가 들어가 있는지 바로 확인할 수 있음
페이징 시스템과 MMU
- CPU에서 가상주소 접근하면 MMU를 통해 물리주소를 받아올 수 있음
- 프로세스를 생성하면 CR3 레지스터에 Page Table의 Base주소를 저장
- MMU는 CPU가 요청한 가상 주소에 해당하는 물리주소를 Page Table에 접근하여 가져옴
다중 단계 페이징 시스템
- 프로세스에서 할당된 모든 가상 메모리에 대한 페이지 정보를 Page Table에 저장하는 것은 굉장한 낭비
- 페이지 정보를 단계를 나눠 생성하여 필요한 페이지만 생성하여 자원을 절약
- Page Table을 Directory로 한 단계 더 거쳐 접근하도록 하여 실제 존재하는 Page Table만 관리할 수 있도록 함
- Page Directory는 실제로 존재하는 Page Table만을 연결하여 만듬
MMU와 TLB
- MMU가 동작할 때 데이터의 이동이 잦음
- CPU에서 가상주소로 요청 → MMU에서 PageTable에 접근하여 물리 주소 획득 → 획득한 물리 메모리 주소로 가서 데이터 획득 → CPU에 획득한 데이터 전달
- 해당 동작의 반복을 줄이기 위해 TLB를 통해 가상주소에 대한 물리주소를 캐싱하여 동작을 줄일 수 있음
- CPU에서 가상주소를 요청했을 때 먼저 TLB를 확인하여 캐싱된 물리주소가 있다면 바로 처리
페이징 시스템과 공유 메모리
- 프로세스 사이에서 동일한 물리 주소를 가르킬 수 있음
- 대표적으로 모든 프로세스의 커널 영역의 경우 물리메모리에서 동일한 주소를 갖고있음
- 하나의 프로세스를 Fork하여 프로세스를 복사하여 만들 경우 복사된 가상 메모리는 부모 프로세스와 같은 물리메모리를 공유하고 해당 프로세스에서 데이터가 수정될 경우 그 때 새롭게 물리 메모리를 할당함
요구 페이징 (Demand Paging 또는 Demanded Paiging)
- 선행 페이징과 반대되는 개념
- 프로세스의 데이터를 모두 메모리에 올리지 않고 실행 중 필요한 시점에서 메모리에 적재하는 기법
- 중간에 필요가 없어진 페이지 프레임은 다시 저장매체에 저장 (페이지 교체 알고리즘)
페이지 폴트 인터럽트 (Page Fault Interrupt)
- 필요한 페이지가 물리 메모리에 없을 때 일어나는 인터럽트
- Page Fault가 일어나면 해당하는 페이지를 물리 메모리에 올리게 됨
- Page Fault가 자주 일어나게 되면 성능에 영향이 생기기 때문에 최적화를 해줘야 함
- 자주 사용되거나 반드시 사용될 데이터는 미리 물리 메모리에 올려놓는 알고리즘을 구성
- Page Fault가 발생할 때는 외부 저장장치와 통신이 발생하기 때문에 병목이 발생할 수 있음
페이지 교체 정책 (Page Replacement Policy)
- 새로운 페이지를 물리 메모리에 올려야 하는 상황에 물리 메모리가 부족할 때
- 기존에 올라와 있던 페이지 중 하나를 물리메모리에서 내리고 외부 저장장치에 저장한 뒤
- 새로운 페이지를 해당 공간에 올린다
- 이 때, 기존에 올라와 있던 페이지 중 어떤 페이지를 내려야 할 지 선택하는 것이 페이지 교체 정책
FIFO
- 가장 먼저 올라온 페이지가 가장 먼저 교체됨
OPT
- OPTimal Repacement Algorithm
- 앞으로 가장 오랫동안 사용하지 않을 페이지가 먼저 교체됨
- 그러나 가장 오랫동안 사용하지 않을 페이지를 알아내는 것은 사실상 불가능
- 일반적인 OS에서는 구현 불가능
LRU
- Least Recently Used
- 가장 오래 전에 사용된 페이지를 교체
- 가장 많이 사용되는 알고리즘
LFU
- Least Frequently Used
- 가장 적게 사용된 페이지를 교체
NUR
- Not Used Recently
- NRU와 같지만 각 페이지 마다 참조 비트와 수정 비트를 넣어 사용빈도가 낮은 페이지부터 교체되도록 우선순위를 추가한다
- (참조, 수정)으로 했을 때 (0, 0), (0, 1), (1, 0), (1, 1) 순으로 페이지를 교체
스레싱
- 페이지 폴트가 너무 많이 발생하여 과도한 페이지 교체 작업으로 인해 CPU 동작이 중단되는 상황
세그멘테이션
- 가상 메모리를 서로 크기가 다른 논리적 단위인 세그먼트로 분할해서 관리하는 방법
- 페이징 기법과 다르게 각 블록의 크기가 다를 수 있음
- 각 세그먼트별로 역할이나 의미를 갖는 경우가 많음
- 페이징 방식과 물리주소 계산방식은 유사하다
- 가상주소로 요청을 들어오면 세그먼트 테이블에서 물리메모리의 기준주소와 오프셋을 더해 실제 주소를 받아올 수 있음