CPU와 프로세스는 메모리의 하드웨어 상 실제 주소인 물리 주소가 아니라 다른 주소 체계를 이용
이 문제를 해결하기 위해 "MMU (메모리 관리 장치)"가 필요
CPU와 메모리 사이에 위치하며, CPU가 이해하는 논리 주소를 메모리가 이해하는 물리 주소로 변환

실행 중이 아닌 프로세스를 스왑 영역으로 이동시켜 메모리 공간을 확보하는 기법
1️⃣ 메모리에 현재 실행되지 않는 대기 상태 프로세스를 스왑 영역으로 이동 (스왑 아웃)
2️⃣ 새로운 프로세스를 실행하기 위해 확보된 메모리 공간을 사용
3️⃣ 스왑 아웃된 프로세스가 다시 필요하면 메모리로 이동 (스왑 인)

프로세스가 연속적인 메모리 공간을 할당받아 실행되는 방식
1️⃣ 프로세스 A가 메모리에 적재 → A의 크기만큼 연속적인 공간 차지
2️⃣ 프로세스 B가 메모리에 적재 → A의 뒤에 B의 크기만큼 연속적인 공간 차지
3️⃣ 프로세스 C가 메모리에 적재 → B의 뒤에 C의 크기만큼 연속적인 공간 차지
4️⃣ 프로세스 B가 종료되면 빈 공간 발생 (외부 단편화 문제 발생 가능)
이 문제를 해결하기 위해 "페이징" 방식 도입
실행하고자 하는 프로그램의 일부만 메모리에 적재해, 실제 메모리보다 더 큰 프로세스를 실행할 수 있도록 만드는 메모리 관리 기법
> 가상 메모리 기법으로 생성된 논리 주소 공간은 "가상주소공간"이라고도 부름
세그멘테이션 (Segmentation)
또 다른 가상 메모리 기법
프로세스를 일정한 크기의 페이지 단위가 아닌 가변적인 크기의 세그먼트 단위로 분할하는 방식
페이징 기법처럼 프로세스를 나누는 단위가 일정하지 않더라도 유의미한 논리적 단위로 분할하는 방식
한 세그먼트는 코드 영역(의 일부)일 수도 있고, 데이터 영역(의 일부)일 수도 있음
세그멘테이션 기법을 사용하면 세그먼트의 크기가 일정하지 않기 때문에 외부 단편화가 발생할 수 있음
프로세스의 논리 주소와 물리 주소를 매핑하는 데이터 구조

페이지 테이블은 여러 개의 페이지 테이블 엔트리(Page Table Entry, PTE) 로 구성

해당 페이지에 접근이 가능한지 여부를 알려 주는 매우 중요한 정보
1️⃣ 기존 작업 내역을 백업
2️⃣ 페이지 폴트 처리 루틴을 실행
> 페이지 폴트 처리 루틴: 원하는 페이지를 메모리로 가져와 유효 비트를 1로 변경 해주는 작업
3️⃣ 페이지 폴트 처리 루틴 실행후, 메모리에 적재된 페이지를 실행
페이지 보호 기능을 위해 존재하는 비트
CPU가 해당 페이지에 접근한 적이 있는지의 여부를 나타내는 비트
해당 페이지에 데이터를 쓴 적이 있는지의 여부를 알려주는 비트
> 더티비트 라고도 부름
페이지 하나의 크기보다 작은 크기로 발생하게 되는 메모리 낭비

문제: 페이지 테이블이 메모리에 존재하면, CPU는 메모리에 두 번 접근해야 함
> 페이지 테이블 접근 (1회) → 프레임 접근 (1회) = 총 2회 접근 필요
해결책: TLB(Translation Lookaside Buffer) 사용
> TLB
- 페이지 테이블을 빠르게 조회하기 위한 캐시 메모리
- TLB는 페이지 테이블의 일부를 저장하여, 메모리 접근을 줄이는 역할 수행
TLB 동작 원리
1️⃣ CPU가 논리 주소(페이지 번호)를 요청
2️⃣ TLB에서 해당 페이지 번호가 있는지 조회
TLB 성능 최적화
문제: 페이지 테이블이 너무 커질 경우, 메모리를 과도하게 차지
해결책: 계층적 페이징(Hierarchical Paging, 다단계 페이지 테이블)
> 계층적 페이징
- 페이지 테이블을 페이징하는 방식
계층적 페이징 동작 방식
1️⃣ CPU는 PTBR을 통해 Outer 페이지 테이블을 참조
2️⃣ Outer 페이지 테이블은 Inner 페이지 테이블(실제 페이지 테이블)의 주소를 제공
3️⃣ Inner 페이지 테이블을 통해 물리 메모리의 프레임을 찾음
페이지 테이블의 계층은 3개, 4개, 그 이상으로도 구성될 수 있음
하나의 페이지 내에는 여러 주소가 포함되어 있기 때문에 페이징 시스템의 논리 주소는 기본적으로 〈페이지번호, 변위>와 같은 형태로 이루어져 있음
〈페이지 번호, 변위〉로 이루어진 논리 주소는 페이지 테이블을 통해 물리 주소〈프레임번호, 변위〉로 변환
프로세스를 실행할 때 처음부터 모든 페이지를 적재하지 않고, 필요한 페이지만 메모리에 적재하는 기법
1️⃣ CPU가 특정 페이지에 접근하는 명령어를 실행
2️⃣ 해당 페이지가 현재 메모리에 있을 경우(유효 비트가 1일 경우) CPU는 페이지가 적재된 프레임에 접근
3️⃣ 해당 페이지가 현재 메모리에 없을 경우(유효 비트가 0일 경우) 페이지 폴트 발생
4️⃣ 페이지 폴트가 발생하면 페이지 폴트 처리 루틴을 통해 해당 페이지를 메모리로 적재하고, 유효 비트를 1로 실행
5️⃣ 다시 1️⃣의 과정 수행
아무런 페이지도 메모리에 적재하지 않은채 무작정 프로세스를 실행
메모리가 가득 찬 상태에서 새로운 페이지를 적재해야 할 경우, 어떤 페이지를 제거할지 결정하는 방법
스래싱(thrashing)
지나친 페이지 교체로 인한 성능저하
스래싱은 프로세스가 실제로 실행되는 시간보다 페이징에 더 많은 시간을 소요하여 성능이 저하되는 문제
1️⃣ FIFO 페이지 교체 알고리즘
2️⃣ 최적 페이지 교체 알고리즘
3️⃣ LRU 페이지 교체 알고리즘
페이지 폴트의 종류
메이저 페이지 폴트: 보조기억장치에서 CPU가 원하는 페이지를 읽어 들이기 위해 입출력 작업이 필요한 페이지 폴트. CPU가 접근하려는 페이지가 물리 메모리에 없을때 발생하는 페이지 폴트로 볼 수 있음
마이너 페이지 폴트: 보조기억장치와의 입출력이 필요하지 않은 페이지 폴트. CPU가 요청한 페이지가 물리 메모리에는 존재하지만, 페이지 테이블상에는 반영되지 않은 경우에 발생 할 수 있음
일반적으로 메이저 페이지 폴트에 비해 성능상의 악영향이 적은 페이지 폴트
참고: 북스터디 - 이것이 취업을 위한 컴퓨터 과학이다 (Chapter 3-5)