[CS] 가상메모리

눈치없어·2025년 2월 20일

물리 주소와 논리 주소

CPU와 프로세스는 메모리의 하드웨어 상 실제 주소인 물리 주소가 아니라 다른 주소 체계를 이용

논리 주소(Logical Address)

  • 프로세스마다 부여되는 0번지부터 시작하는 주소 체계
  • CPU가 이해하는 주소
  • 물리 주소가 아니라 논리 주소기 때문에 서로 다른 프로세스가 같은 논리 주소를 사용할 수 있음

물리 주소(Physical Address)

  • 실제 메모리의 하드웨어상 주소
  • 메모리가 이해하는 주소
  • 중복 불가능한 고유한 주소

문제점

  • 프로세스는 논리 주소를 사용하지만, 실제 메모리는 물리 주소로 동작함
  • CPU는 논리 주소만 알고 있으며, 물리 주소로 변환하는 과정이 필요

    이 문제를 해결하기 위해 "MMU (메모리 관리 장치)"가 필요


MMU (Memory Management Unit)

CPU와 메모리 사이에 위치하며, CPU가 이해하는 논리 주소를 메모리가 이해하는 물리 주소로 변환

  • 운영체제가 직접 주소 변환을 수행하는 것이 아니라 MMU가 자동으로 처리
  • 모든 프로세스가 독립적인 메모리 공간을 사용할 수 있도록 보장


스와핑과 연속 메모리 할당

스와핑

실행 중이 아닌 프로세스를 스왑 영역으로 이동시켜 메모리 공간을 확보하는 기법

  • 효율적인 메모리 활용을 위해 사용됨
  • 스왑 아웃(Swap-Out): 메모리에 있던 프로세스를 보조 기억 장치로 이동
  • 스왑 인(Swap-In): 보조 기억 장치에 있던 프로세스를 다시 메모리로 적재

📌 운영 방식

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


연속 메모리 할당

프로세스가 연속적인 메모리 공간을 할당받아 실행되는 방식

  • 각 프로세스가 일정한 크기의 연속적인 물리적 메모리 공간을 차지함
  • 단순하고 직관적인 메모리 관리 방식이지만, 외부 단편화 문제를 초래할 수 있음

📌 운영 방식

1️⃣ 프로세스 A가 메모리에 적재 → A의 크기만큼 연속적인 공간 차지
2️⃣ 프로세스 B가 메모리에 적재 → A의 뒤에 B의 크기만큼 연속적인 공간 차지
3️⃣ 프로세스 C가 메모리에 적재 → B의 뒤에 C의 크기만큼 연속적인 공간 차지
4️⃣ 프로세스 B가 종료되면 빈 공간 발생 (외부 단편화 문제 발생 가능)

📌 외부 단편화

  • 연속 메모리 할당 방식에서는 프로세스가 실행되고 종료될 때, 남는 공간이 조각조각 남아 효율적으로 사용되지 못하는 현상
  • 예: 총 50MB의 빈 공간이 있지만, 각각 30MB와 20MB로 나뉘어 있어 50MB 크기의 프로세스를 적재할 수 없음
  • 메모리 낭비 발생 가능

이 문제를 해결하기 위해 "페이징" 방식 도입




페이징을 통한 가상 메모리 관리

가상 메모리

실행하고자 하는 프로그램의 일부만 메모리에 적재해, 실제 메모리보다 더 큰 프로세스를 실행할 수 있도록 만드는 메모리 관리 기법

> 가상 메모리 기법으로 생성된 논리 주소 공간은 "가상주소공간"이라고도 부름

페이징

  • 프로세스의 논리 주소 공간을 일정한 크기의 페이지 단위로 나누고,
  • 물리 주소 공간도 페이지와 동일한 크기의 프레임 단위로 나누고,
  • 페이지를 프레임에 할당하는 가상 메모리 관리 기법

세그멘테이션 (Segmentation)
또 다른 가상 메모리 기법
프로세스를 일정한 크기의 페이지 단위가 아닌 가변적인 크기의 세그먼트 단위로 분할하는 방식
페이징 기법처럼 프로세스를 나누는 단위가 일정하지 않더라도 유의미한 논리적 단위로 분할하는 방식
한 세그먼트는 코드 영역(의 일부)일 수도 있고, 데이터 영역(의 일부)일 수도 있음
세그멘테이션 기법을 사용하면 세그먼트의 크기가 일정하지 않기 때문에 외부 단편화가 발생할 수 있음

📌 페이징 사용 시

  • 외부 단편화 문제 해결
  • 프로세스의 일부만 적재 가능 → 더 큰 프로세스 실행 가능
  • 스와핑 활용 가능
    - 페이징 시스템에서의 스왑 아웃은 페이지 아웃, 스왑 인은 페이지 인

페이지 테이블

프로세스의 논리 주소와 물리 주소를 매핑하는 데이터 구조

  • 각 프로세스마다 개별적인 페이지 테이블을 가짐
  • 논리 주소의 페이지 번호 → 물리 주소의 프레임 번호로 변환
  • 페이지 테이블을 참조하여 CPU가 올바른 메모리 위치를 찾아 실행

📌 페이지 테이블의 구성 요소

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

📌 유효 비트

해당 페이지에 접근이 가능한지 여부를 알려 주는 매우 중요한 정보

  • 유효 비트 = 1 → 페이지가 메모리에 있음 (즉시 접근 가능)
  • 유효 비트 = 0 → 페이지가 메모리에 없음 → 페이지 폴트(Page Fault) 발생
  • 페이지 폴트 발생 시, 해당 페이지를 보조 기억 장치(디스크)에서 메모리로 가져오는 과정 수행
페이지 폴트 처리 과정

1️⃣ 기존 작업 내역을 백업
2️⃣ 페이지 폴트 처리 루틴을 실행

> 페이지 폴트 처리 루틴: 원하는 페이지를 메모리로 가져와 유효 비트를 1로 변경 해주는 작업

3️⃣ 페이지 폴트 처리 루틴 실행후, 메모리에 적재된 페이지를 실행

📌 보호 비트

페이지 보호 기능을 위해 존재하는 비트

  • 페이지 보호를 위해 읽기(Read), 쓰기(Write), 실행(eXecute) 권한을 설정
  • 예시:
    - 100 → 읽기 가능, 쓰기/실행 불가능
    - 111 → 읽기, 쓰기, 실행 모두 가능

📌 참조 비트

CPU가 해당 페이지에 접근한 적이 있는지의 여부를 나타내는 비트

  • 페이지에 적재한 이후에 CPU가 읽거나 쓴페이지는 참조비트가 1로 설정
  • 적재한 이후에 한번도 읽거나 쓴적이 없는 페이지는 0으로 유지

📌 수정 비트

해당 페이지에 데이터를 쓴 적이 있는지의 여부를 알려주는 비트

> 더티비트 라고도 부름
  • 페이지가 수정된 경우(1) 보조기억장치(디스크)에도 변경 내용을 반영해야 함
  • 수정되지 않은 경우(0) 단순히 메모리에서 제거 가능 (디스크에 다시 저장할 필요 없음)

내부 단편화

페이지 하나의 크기보다 작은 크기로 발생하게 되는 메모리 낭비


페이지 테이블 관리 및 최적화 기법

  • 페이지 테이블은 메모리에 적재될 수 있음
  • CPU가 특정 프로세스를 실행하려면 해당 프로세스의 페이지 테이블이 메모리에 위치해야 함
  • CPU는 페이지 테이블의 위치를 알기 위해 특별한 레지스터를 사용

📌 페이지 테이블 베이스 레지스터(PTBR, Page Table Base Register)

  • 프로세스마다 가지는 정보이므로 각 PCB에 기록
  • 문맥 교환 시 변경됨

📌 메모리 접근 횟수 문제 상황과 해결 방법

문제: 페이지 테이블이 메모리에 존재하면, CPU는 메모리에 두 번 접근해야 함

> 페이지 테이블 접근 (1회) → 프레임 접근 (1회) = 총 2회 접근 필요

해결책: TLB(Translation Lookaside Buffer) 사용

> TLB 
  - 페이지 테이블을 빠르게 조회하기 위한 캐시 메모리
  - TLB는 페이지 테이블의 일부를 저장하여, 메모리 접근을 줄이는 역할 수행

TLB 동작 원리
1️⃣ CPU가 논리 주소(페이지 번호)를 요청
2️⃣ TLB에서 해당 페이지 번호가 있는지 조회

  • TLB 히트(TLB Hit) → TLB에서 프레임 번호를 찾음 → 빠른 접근 가능 (1회 메모리 접근)
  • TLB 미스(TLB Miss) → 메모리에 있는 페이지 테이블을 검색해야 함 (추가 메모리 접근 필요)

TLB 성능 최적화

  • TLB 히트율(TLB Hit Rate)이 높을수록 성능 향상

📌 메모리 용량 문제 상황과 해결 방법

문제: 페이지 테이블이 너무 커질 경우, 메모리를 과도하게 차지

  • 프로세스 크기가 커질수록 페이지 테이블의 크기도 증가
  • 모든 페이지 테이블을 메모리에 유지하는 것은 메모리 낭비

해결책: 계층적 페이징(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)
지나친 페이지 교체로 인한 성능저하
스래싱은 프로세스가 실제로 실행되는 시간보다 페이징에 더 많은 시간을 소요하여 성능이 저하되는 문제


📌 대표적인 페이지 교체 알고리즘 3가지

1️⃣ FIFO 페이지 교체 알고리즘

  • 가장 먼저 메모리에 들어온 페이지부터 교체하는 방식
  • 장점: 구현이 단순함
  • 단점: 초기에 적재된 자주 사용되는 페이지도 교체될 위험이 있어 비효율적

2️⃣ 최적 페이지 교체 알고리즘

  • 앞으로 가장 오랫동안 사용되지 않을 페이지를 제거하는 방식
  • 이론적으로 가장 낮은 페이지 폴트율을 보장하지만, 미래의 페이지 사용을 예측해야 하기 때문에 현실적으로 구현이 어려움

3️⃣ LRU 페이지 교체 알고리즘

  • 가장 오랫동안 사용되지 않은 페이지를 교체하는 방식
  • 현실적으로 가장 많이 사용되며, 이를 기반으로 한 다양한 변형 알고리즘 존재

페이지 폴트의 종류
메이저 페이지 폴트: 보조기억장치에서 CPU가 원하는 페이지를 읽어 들이기 위해 입출력 작업이 필요한 페이지 폴트. CPU가 접근하려는 페이지가 물리 메모리에 없을때 발생하는 페이지 폴트로 볼 수 있음
마이너 페이지 폴트: 보조기억장치와의 입출력이 필요하지 않은 페이지 폴트. CPU가 요청한 페이지가 물리 메모리에는 존재하지만, 페이지 테이블상에는 반영되지 않은 경우에 발생 할 수 있음
일반적으로 메이저 페이지 폴트에 비해 성능상의 악영향이 적은 페이지 폴트



참고: 북스터디 - 이것이 취업을 위한 컴퓨터 과학이다 (Chapter 3-5)

profile
dock 사이즈 다르잖아

0개의 댓글