스와핑
- 현재 사용되지 않는 프로세스들을 보조기억장치의 일부 영역으로 쫓아내고 그렇게 생긴 빈 공간에 새 프로세스 적재


- 프로세스들이 요구하는 메모리 공간 크기 > 실제 메모리 크기
- 스왑 영역 크기 확인하기: free, top 명령어
연속 메모리 할당
- 프로세스는 메모리의 빈 공간에 할당되어야 한다. 빈 공간이 여러 개라면?
- 최초 적합, 최적 적합, 최악 적합 - 빈공간에 어떤 식으로 적재할 지 (연속 메모리 할당 방식)
- 단점 - 외부 단편화, 물리 메모리보다 큰 프로세스 실행 불가

- 최초 적합 (first-fit)
- 운영체제가 메모리 내의 빈 공간을 순서대로 검색하다 적재할 수 있는 공간을 발견하면, 그 공간에 프로세스를 배치하는 방식
- 검색 최소화, 빠른 할당
- 최적 적합 (best-fit)
- 운영체제가 빈 공간을 모두 검색해본 뒤, 적재 가능한 가장 작은 공간에 할당
- 최악 적합 (worst-fit)
- 운영체제가 빈 공간을 모두 검색해본 뒤, 적재 가능한 가장 큰 공간에 할당
외부 단편화 (external fragmentation)
- 프로세스를 연속적으로 메모리에 할당하는 방식은 메모리를 효율적으로 사용하는 방법이 아님 -> 외부 단편화 발생
- 프로세스들이 실행되고 종료되길 반복하며 메모리 사이 사이에 빈 공간 발생
- 프로세스를 할당하기 어려울 만큼 작은 메모리 공간들로 인해 메모리가 낭비되는 현상

외부 단편화 해결
메모리 압축 (compaction)
- 여기저기 흩어져 있는 빈 공간들을 하나로 모으는 방식
- 프로세스들을 적당히 재배치시켜 흩어져 있는 작은 빈 공간들을 하나의 큰 빈 공간으로 만드는 방법
- 부작용으로 오버헤드 발생
가상 메모리 기법
- 가상 메모리
- 실행하고자 하는 프로그램을 일부만 메모리에 적재하여 실제 물리 메모리 크기보다 더 큰 프로세스를 실행할 수 있게 하는 기술
- 페이징, 세그멘테이션
- 외부 단편화가 발생했던 근본적인 문제 -> 각기 다른 크기의 프로세스가 메모리에 연속적으로 할당되었기 때문
- 페이징 (paging)
- 프로세스의 논리 주소 공간을 페이지(page)라는 일정 단위로 자르고, 메모리의 물리 주소 공간을 프레임(frame)이라는 페이지와 동일한 일정한 단위로 자른 뒤 페이지를 프레임에 할당하는 가상 메모리 관리 기법
- 페이징에서의 스와핑
- 프로세스 단위의 스왑 인, 스왑 아웃이 아닌 페이지 단위의 스왑 인(페이지 인), 스왑 아웃(페이지 아웃)
- 메모리에 적재될 필요가 없는 페이지들은 보조기억장치로 스왑 아웃
- 실행에 필요한 페이지들은 메모리로 스왑 인
- 프로세스를 실행하기 위해 모든 페이지가 적재될 필요 없음 (= 물리 메모리보다 큰 프로세스도 실행될 수 있음)
- 페이징의 문제
- 프로세스를 이루는 페이지가 어느 프레임에 적재되어 있는지 CPU가 일일이 알기란 어려움
- 프로세스가 메모리에 불연속적으로 배치되어 있다면 CPU 입장에서 이를 순차적으로 실행할 수가 없음
- CPU 입장에서 '다음에 실행할 명령어 위치'를 찾기가 어려워짐


- 페이지 테이블
- (실제 메모리 내의 주소인) 물리 주소에 불연속적으로 배치되더라도 (CPU가 바라보는 주소인) 논리 주소에는 연속적으로 배치되도록 하는 방법
- 페이지 번호가 프레임 번호를 짝지어 주는 일종의 이정표
- 즉 물리적으로는 분산되어 저장되어 있더라도 CPU 입장에서 바라본 논리 주소는 연속적으로 보임 -> CPU는 그저 논리 주소를 순차적으로 실행하면 될 뿐
- 내부 단편화
- 하나의 페이지 크기보다 작은 크기로 발생


PTBR
- 프로세스마다 페이지 테이블이 있고, PTBR(프로세스 테이블 베이스 레지스터)는 각 프로세스의 페이지 테이블이 적재된 주소를 가리킴

- 페이지 테이블이 메모리에 있으면 -> 메모리 접근 시간이 두 배 (페이지 테이블 접근, 프레임 접근)
TLB
- CPU 곁에 페이지 테이블의 캐시 메모리
- 페이지 테이블의 일부를 가져와 저장
- CPU가 접근하려는 논리 주소가 TLB에 있다면 -> TLB 히트 (메모리 접근 한 번)
- CPU가 접근하려는 논리 주소가 TLB에 없다면 -> TLB 미스 (메모리 접근 두 번)

페이징에서의 주소 변환
- 특정 주소에 접근하려면 -> 어떤 페이지/프레임에 접근하고 싶은지, 접근하려는 주소가 그 페이지 혹은 프레임으로부터 얼마나 떨어져 있는지 정보 필요
- 페이징 시스템에서의 논리 주소
- 페이지 번호(page number)와 변위(offset)
- <페이지 번호, 변위>로 이루어진 논리 주소는 페이지 테이블을 통해 <프레임 번호, 변위>로 반환

- 페이지 테이블 엔트리
- 페이지 테이블의 각각의 행: 페이지 테이블 엔트리(PTE)
- 페이지 번호, 프레임 번호, ... 등
- 유효 비트
- 현재 해당 페이지에 접근 가능한지 여부
- 유효 비트가 0인 페이지에 접근하려고 하면 페이지 폴트(page fault)라는 인터럽트 발생
- CPU는 기존의 작업 내역을 백업
- 페이지 포트 처리 루틴을 실행
- 페이지 처리 루틴은 원하는 페이지를 메모리로 가져온 뒤 유효 비트를 1로 변경
- 페이지 폴트를 처리했다면 이제 CPU는 해당 페이지에 접근 가능
- 보호 비트
- 페이지 보호 기능을 위해 존재하는 비트 (페이지에 접근할 권한을 제한)
- 참조 비트
- CPU가 이 페이지에 접근한 적이 있는지 여부
- 수정 비트 (=dirty bit)
- CPU가 이 페이지에 데이터를 쓴 적이 있는지 여부 (수정된 적 있/없)
- 수정된 페이지는 스왑 아웃될 때 보조기억장치에도 쓰기 작업을 거쳐서 반영해야 함



쓰기 시 복사
- 이론적인 fork()
- 프로세스는 기본적으로 자원을 공유하지 않음 -> 부모 프로세스가 적재된 별도의 공간에 자식 프로세스가 통째로 복제되어 적재 (프로세스 생성 시간 지연, 메모리 낭비)

- 쓰기 시 복사
- 부모 프로세스와 동일한 자식 프로세스가 복제되어 생성되면, 자식 프로세스는 부모 프로세스와 동일한 프레임을 가리킴 (쓰기 작업 없다면 이 상태 유지)
- 부모 프로세스/자식 프로세스 둘 중 하나가 페이지에 쓰기 작업 수행 시 해당 페이지는 별도의 공간으로 복제 (프로세스 생성 시간 절약, 메모리 절약)


계층적 페이징
- 프로세스 테이블의 크기는 생각보다 작지가 않음
- 프로세스를 이루는 모든 페이지 테이블 엔트리를 메모리에 두는 것은 큰 낭비
- 페이지 테이블을 페이징하여 여러 단계의 페이지를 두는 방식
- 페이지 테이블을 여러 페이지로 쪼개고, 이 페이지를 가리키는 페이지 테이블(Outer 페이지 테이블)을 두는 방식

- CPU와 가장 가까이 위치한 Outer 페이지 테이블만 항상 메모리에 유지하고, 모든 페이지 테이블을 항상 메모리에 둘 필요는 없어짐
- 계층적 페이징의 논리주소
- 바깥 페이지 번호, 안쪽 페이지 번호, 변위
- 바깥 페이지 번호를 통해 페이지 테이블의 페이지 찾기
- 페이지 테이블의 페이지를 통해 프레임 번호를 찾고 변위를 더함으로서 물리 주소 얻기

=> 가상 메모리 기법으로 물리 메모리보다 큰 프로레스를 실행할 수 있지만, 그럼에도 물리 메모리의 크기는 한정되어 있다.
=> 즉, 운영체제는 기존에 적재된 불필요한 페이지를 선별해 보조 기억 장치로 내보내고, 프로세스들에게 적절한 수의 프레임을 할당할 수 있어야 한다.
요구 페이징
처음부터 모든 페이지를 적재하지 않고 필요한 페이지만을 메모리에 적재하는 기법 (=요구되는 페이지만 적재)
- CPU가 특정 페이지에 접근하는 명령어를 실행
- 해당 페이지가 현재 메모리에 있을 경우(유효 비트가 1일 경우) CPU는 페이지가 적재된 프레임에 접근
- 해당 페이지가 현재 메모리에 없을 경우(유효 비트가 0일 경우) 페이지 폴트가 발생
- 페이지 폴트 처리 루틴은 해당 페이지를 메모리로 적재하고 유효 비트를 1로 설정
- 다시 1번을 수행
=> 요구 페이징 시스템이 안정적으로 작동하려면 -> 페이지 교체, 프레임 할당
페이지 교체 알고리즘
- 요구 페이징 기법으로 페이지들을 적재하다보면 언젠간 메모리가 가득 차게 됨
- 당장 실행에 필요한 페이지를 적재하려면, 적재된 페이지를 보조기억장치로 내보내야 함 -> 어떤 페이지를 내보낼지 결정하는 알고리즘
- 좋은 페이지 교체 알고리즘이란? 페이지 폴트가 적은 알고리즘!
- 페이지 폴트가 발생하면 보조기억장치에 접근해야 해서 성능 저하
- 페이지 참조열 (page reference string)
- CPU가 참조하는 페이지들 중 연속된 페이지를 생략한 페이지열
- FIFO 페이지 교체 알고리즘
- 가장 단순한 방식으로, 메모리에 가장 먼저 올라온 페이지부터 내쫓는 방식 (오래 머물렀다면 나가라)
- 보완책 - 2차 기회(second-chance) 페이지 교체 알고리즘
- 참조 비트 1: CPU가 한 번 참조한 적이 있는 페이지 (한번 더 기회를 주기)
- 참조 비트 0: CPU가 참조한 적이 없는 페이지 (내쫓기)

- 최적 페이지 교체 알고리즘
- CPU에 의해 참조되는 횟수를 고려
- 메모리에 오래 남아야 할 페이지는 자주 사용될 페이지
- 메모리에 없어도 될 페이지는 오랫동안 사용되지 않을 페이지
- 가장 낮은 페이지 폴트율을 보장하는 페이지 교체 알고리즘, But 실제 구현이 어려움 (어떻게 앞으로 오랫동안 사용되지 않을 페이지를 예측할지)
- 다른 페이지 교체 알고리즘 성능을 평가하기 위한 하한선으로 간주

- LRU(Least-Recently-Used) 페이지 교체 알고리즘
- 최적 페이지 교체 알고리즘: 가장 오래 사용되지 않을 페이지 교체
- LRU 페이지 교체 알고리즘: 가장 오래 사용되지 않은 페이지 교체

스래싱과 프레임 할당
- 페이지 폴트가 자주 발생하는 이유
- 나쁜 페이지 교체 알고리즘을 사용해서
- 프로세스가 사용할 수 있는 프레임 자체가 적어서
스래싱
- 프로세스가 실행되는 시간보다 페이징에 더 많은 시간을 소요하여 성능(CPU 이용률)이 저해되는 문제
- 동시 실행되는 프로세스의 수를 늘린다고 CPU 이용률이 높아지는 것이 아님
- 각 프로세스가 필요로 하는 최소한의 프레임 수가 보장되지 않았기 때문 -> 각 프로세스가 필요로 하는 최소한의 프레임 수를 파악하고 프로세스들에게 적절한 프레임을 할당해주어야 함

프레임 할당
- 균등 할당 (equal allocation)
- 가장 단순한 할당 방식으로, 모든 프로세스들에게 균등하게 프레임을 할당하는 방식
- 비례 할당 (proportional allocation)
- 프로세스의 크기에 비례하여 프레임 할당 (=정적 할당 방식)
- But, 결국 프로세스가 필요로 하는 프레임의 수는 실행해봐야 아는 것
- 작업 집합 모델
- 프로세스가 실행하는 과정에서 배분할 프레임 결정 (=동적 할당 방식)
- 스레싱이 발생하는 이유는 빈번한 페이지 교체 때문 -> 그렇다면 CPU가 특정 시간 동안 주로 참조한 페이지 개수만큼만 프레임을 할당하면 됨
- '프로세스가 일정 기간 동안 참조한 페이지 집합'을 기억하여 빈번한 페이지 교체를 방지
- 작업 집합이란 '실행 중인 프로세스가 일정 시간 동안 참조한 페이지의 집합'
- 작업 집합을 구하려면 프로세스가 참조한 페이지와 시간 간격이 필요
- 프로세스가 실행하는 과정에서 배분할 프레임 결정 (=동적 할당 방식)

- 페이지 폴트 빈도 기반 프레임 할당
- 프로세스가 실행하는 과정에서 배분할 프레임 결정 (=동적 할당 방식)
- 두 개의 가정에서 생겨난 아이디어
- 페이지 폴트율이 너무 높으면 그 프로세스는 너무 적은 프레임을 갖고 있다.
- 페이지 폴트율이 너무 낮으면 그 프로세스가 너무 많은 프레임을 갖고 있다.
- 페이지 폴트율에 상한선과 하한선을 정하고, 그 내부 범위 안에서만 프레임을 할당하는 방식

'CS' 카테고리의 다른 글
| 자료구조 정리 (0) | 2026.07.08 |
|---|---|
| [운영체제] 파일과 디렉터리 (0) | 2026.07.08 |
| [운영체제] 교착 상태 (0) | 2026.07.06 |
| [운영체제] 프로세스 동기화 (0) | 2026.07.06 |
| [운영체제] CPU 스케줄링 (0) | 2026.07.04 |