본문 바로가기
운영체제/반효경 교수

운영체제: 메모리 관리 ③ - 페이징 심화 및 세그멘테이션

by 절차탁마 2025. 4. 14.

지난 글에서는 페이징(Paging)의 기본 개념과 TLB, 다중 레벨 페이징에 대해 알아보았습니다. 페이징은 외부 단편화를 해결하는 강력한 기법이지만, 페이지 테이블 관리의 효율성과 메모리 보호, 공유 등 추가적인 고려 사항들이 있습니다.

 

이번 글에서는 다중 레벨 페이징의 성능 문제, 페이지 테이블의 부가 정보(보호 비트 등), 페이지 테이블 관리의 다른 접근법(역 페이지 테이블), 그리고 페이징과 다른 관점에서 메모리를 관리하는 세그멘테이션(Segmentation) 기법에 대해 자세히 살펴보겠습니다. 마지막으로 이 둘을 결합한 방식까지 소개합니다.

 

 

반효경 [운영체제] 20. Memory Management 3

설명이 없습니다.

core.ewha.ac.kr

 


1. 다중 레벨 페이징과 성능 (Multilevel Paging and Performance)

  • 필요성: 현대 시스템의 거대한 논리 주소 공간 때문에 단일 페이지 테이블은 너무 커서 비효율적입니다. 다중 레벨 페이징은 페이지 테이블 자체를 페이징하여 실제로 사용하는 주소 공간에 대한 페이지 테이블만 메모리에 유지함으로써 공간 효율성을 높입니다.
  • 성능 문제: 주소 변환을 위해 여러 단계의 페이지 테이블을 거쳐야 하므로, 메모리 접근 횟수가 단계 수만큼 증가합니다.
  • 해결책: TLB (Translation Lookaside Buffer)
    • TLB 덕분에 이러한 성능 저하는 대부분 상쇄됩니다. TLB는 논리 페이지 번호와 최종 물리 프레임 번호의 매핑 정보를 캐싱합니다.
    • TLB Hit: TLB에서 매핑 정보를 찾으면, 중간 단계의 페이지 테이블 접근 없이 단 한 번의 메모리 접근으로 실제 데이터에 접근할 수 있습니다.
    • TLB Miss: TLB에 정보가 없으면 다단계 페이지 테이블을 모두 탐색해야 하지만, 지역성(Locality) 원리 덕분에 TLB 적중률(Hit Ratio)은 매우 높게 유지됩니다.
  • 유효 접근 시간 (EAT) 예시 (4단계 페이징): (계산 과정은 이전 글 참조) TLB 적중률이 높으면(예: 98%), 여러 단계의 페이지 테이블 접근에도 불구하고 평균 메모리 접근 시간은 크게 증가하지 않습니다. TLB가 주소 변환 오버헤드를 효과적으로 숨겨줍니다.

[궁금할 수 있는 포인트 🤔 & 답변 ✅]

  • Q: "TLB 적중률이 낮아지면 성능에 어떤 영향이 있나요?"
  • A: TLB 적중률이 낮아지면 TLB Miss가 자주 발생하고, 그럴 때마다 여러 번의 메모리 접근(다단계 페이지 테이블 탐색)이 필요해져 평균 메모리 접근 시간(EAT)이 급격히 증가합니다. 이는 시스템 전체 성능 저하로 이어집니다.

2. 페이지 테이블 항목(Entry)의 부가 정보: 보호와 관리

페이지 테이블의 각 항목(PTE, Page Table Entry)에는 물리 프레임 번호 외에 메모리 보호 및 관리를 위한 부가적인 비트 정보들이 함께 저장됩니다.

  • 유효-무효 비트 (Valid-Invalid Bit, v/i):
    • Valid (v): 해당 페이지가 유효하며, 현재 물리 메모리(프레임)에 적재되어 있다는 의미. 접근 허용.
    • Invalid (i): 해당 페이지가 유효하지 않거나(프로세스가 사용 안 함), 현재 물리 메모리에 없다(디스크에 있음)는 의미. 접근 불허.
    • CPU가 invalid 비트가 설정된 PTE를 참조하면 MMU는 예외(Trap)를 발생시켜 운영체제에게 알립니다 (Segmentation Fault 또는 Page Fault).
  • 보호 비트 (Protection Bit):
    • 해당 페이지에 대한 접근 권한(읽기/쓰기/실행)을 제어합니다.
    • 예: 코드 페이지는 Read/Execute, 데이터 페이지는 Read/Write.
    • 허용되지 않은 접근(예: Read-Only 페이지에 쓰기) 시 MMU가 트랩을 발생시킵니다.

[궁금할 수 있는 포인트 🤔 & 답변 ✅]

  • Q: "Valid/Invalid 비트와 Protection 비트는 어떻게 메모리 보호에 기여하나요?"
  • A: 이 비트들은 MMU가 하드웨어적으로 검사하여 잘못된 메모리 접근을 막습니다. Valid/Invalid 비트는 프로세스가 할당되지 않았거나 메모리에 없는 영역 접근을 막고, Protection 비트는 허용되지 않은 방식(권한 위반)*의 접근을 막아 프로세스 간 메모리 침범 방지 및 오류 조기 발견을 돕습니다.

3. 역 페이지 테이블 (Inverted Page Table): 다른 관점의 매핑

기존 페이지 테이블 방식은 프로세스마다 큰 테이블을 가져 메모리 낭비가 심할 수 있습니다. 역 페이지 테이블은 다른 접근 방식을 취합니다.

  • 핵심 아이디어: 시스템 전체에 물리 메모리 프레임 중심단 하나의 페이지 테이블만 둡니다.
  • 구조: 테이블의 각 항목은 물리 프레임에 대응되며, 해당 프레임에 어떤 프로세스의 어떤 논리 페이지가 있는지 (<process-id, page-number>) 정보를 저장합니다.
  • 주소 변환: 논리 주소 <pid, p, d>가 주어지면, 테이블 전체를 검색하여 (pid, p)와 일치하는 항목의 인덱스(프레임 번호 f)를 찾아야 합니다.
  • 장점: 페이지 테이블 크기가 물리 메모리 크기에 비례하므로 공간을 절약합니다.
  • 단점: 주소 변환 시 테이블 전체 검색이 필요해 매우 느립니다. 이를 보완하기 위해 고가의 연관 메모리나 해싱 기법이 필요합니다. 페이지 공유 구현도 복잡해집니다.
  • 사용 예: 일부 아키텍처에서 사용되었으나 현재는 일반적이지 않습니다.

[궁금할 수 있는 포인트 🤔 & 답변 ✅]

  • Q: "역 페이지 테이블은 왜 테이블 전체를 검색해야 하나요?"
  • A: 기존 방식은 논리 페이지 번호(p)를 인덱스로 바로 사용했지만, 역 페이지 테이블은 인덱스가 물리 프레임 번호(f)이고 내용이 <pid, p>입니다. 우리는 <pid, p>f를 찾아야 하므로, 테이블 내용을 검색해야 합니다.
  • Q: "역 페이지 테이블 방식은 페이지 공유(Shared Page)를 구현하기 어렵지 않나요?"
  • A: 네, 기본 구조상 <pid, p>와 프레임 f가 1:1 매핑되므로, 여러 논리 페이지가 하나의 프레임을 가리키는 공유 구조를 표현하기 더 복잡합니다.

4. 공유 페이지 (Shared Pages): 메모리 절약의 지혜

페이징 시스템은 코드를 공유하여 메모리를 효과적으로 절약할 수 있습니다.

  • 공유 코드 (Shared Code):
    • 여러 프로세스가 동일한 코드(예: C 라이브러리, 편집기 프로그램)를 사용할 때, 해당 코드를 물리 메모리에 한 번만 로드하고, 각 프로세스의 페이지 테이블이 동일한 물리 프레임을 가리키도록 매핑합니다.
    • 조건: 공유 코드는 실행 중 변경되지 않는 재진입 가능 코드(Re-entrant Code 또는 Pure Code)여야 하며, 보통 Read-Only로 보호됩니다.
    • 장점: 메모리 사용량을 크게 줄일 수 있습니다.
  • 개인 데이터 (Private Code and Data):
    • 각 프로세스 고유의 데이터(전역 변수, 힙, 스택 등)는 공유되지 않고 별도의 프레임에 할당됩니다.
  • 주소 공간 위치: 공유 코드는 모든 프로세스의 논리 주소 공간에서 동일한 가상 주소를 가져야 공유가 용이합니다.

[궁금할 수 있는 포인트 🤔 & 답변 ✅]

  • Q: "재진입 가능 코드(Re-entrant Code)란 정확히 무엇인가요?"
  • A: 여러 프로세스(또는 스레드)가 동시에 실행해도 서로에게 영향을 주지 않는 코드입니다. 코드가 실행 중에 자신의 상태(전역/정적 변수 등)를 변경하지 않아야 합니다. 각 실행은 자신만의 스택을 사용하므로 지역 변수는 괜찮습니다. 재진입 가능해야 여러 프로세스가 안전하게 코드를 공유할 수 있습니다.

5. 세그멘테이션 (Segmentation): 의미 단위로 메모리 나누기

페이징과 다른 관점에서 메모리를 관리하는 기법입니다.

  • 개념: 프로그램을 논리적인 의미 단위인 여러 개의 세그먼트(Segment)로 나눕니다. 각 세그먼트는 서로 다른 크기를 가질 수 있습니다. (예: 코드 세그먼트, 데이터 세그먼트, 스택 세그먼트)
  • 논리 주소: <세그먼트 번호 (s), 오프셋 (d)> 두 부분으로 구성됩니다.
  • 세그먼트 테이블 (Segment Table):
    • 각 프로세스마다 존재하며, 각 항목은 세그먼트 정보를 담습니다.
      • 기준(Base): 세그먼트의 물리 메모리 시작 주소.
      • 한계(Limit): 세그먼트의 크기(길이). (크기가 가변적이므로 필수)
    • STBR(Segment-Table Base Register): 세그먼트 테이블의 시작 주소.
    • STLR(Segment-Table Length Register): 세그먼트 개수.
  • 주소 변환 및 보호:
    1. 논리 주소 <s, d> 생성.
    2. s가 유효한지 검사 (s < STLR).
    3. 세그먼트 테이블에서 s 항목을 찾아 baselimit 획득.
    4. 오프셋 d가 유효한지 검사 (d < limit).
    5. 물리 주소 P = base + d 계산.
  • 장점:
    • 의미 단위 관리: 보호(Protection)와 공유(Sharing)가 페이징보다 용이하고 자연스럽습니다. (예: 코드 세그먼트에 실행 권한만 부여)
    • 테이블 크기가 페이징보다 작을 수 있습니다.
  • 단점:
    • 세그먼트 크기가 가변적이므로 외부 단편화(External Fragmentation) 문제가 발생합니다. (가변 분할 연속 할당 방식과 동일한 문제)

[궁금할 수 있는 포인트 🤔 & 답변 ✅]

  • Q: "세그먼테이션에서 Limit 검사는 왜 필요한가요? 페이징에서는 없었는데요."
  • A: 페이징은 페이지 크기가 고정되어 오프셋이 경계를 넘을 일이 없지만, 세그먼테이션은 크기가 가변적이므로 오프셋이 해당 세그먼트의 실제 크기(limit)를 벗어나는지 반드시 검사해야 메모리 침범을 막을 수 있습니다.
  • Q: "세그먼테이션이 보호와 공유에 더 효과적이라는 것은 무슨 의미인가요?"
  • A: '코드 세그먼트' 전체에 실행 권한만 주거나, '공유 라이브러리 세그먼트'를 통째로 공유하는 등 의미 단위로 제어하는 것이 페이지 단위보다 더 직관적이고 관리하기 편할 수 있습니다.

6. 페이지드 세그멘테이션 (Segmentation with Paging): 두 기법의 조화

세그멘테이션의 장점(의미 단위 관리)과 페이징의 장점(외부 단편화 해결)을 결합하려는 시도입니다.

  • 개념:
    • 프로그램을 의미 단위 세그먼트로 나눕니다.
    • 각 세그먼트를 다시 고정 크기 페이지로 나눕니다.
    • 물리 메모리는 프레임 단위로 관리됩니다.
  • 주소 변환: 세그먼트 테이블을 참조하여 해당 세그먼트의 페이지 테이블 주소를 얻고, 다시 페이지 테이블을 참조하여 최종 프레임 번호를 얻는 다단계 변환 방식입니다.
  • 장점: 세그멘테이션의 의미론적 장점을 유지하면서 외부 단편화 문제를 해결합니다.
  • 단점: 주소 변환이 더 복잡하고 메모리 접근 횟수가 증가합니다. 구현 및 관리가 복잡합니다.
  • 현황: 과거 일부 시스템에서 사용되었으나, 현대 범용 OS는 주로 페이징 기반이며, 보호/공유는 페이지 테이블의 부가 비트 등으로 처리하는 경향이 있습니다.

[궁금할 수 있는 포인트 🤔 & 답변 ✅]

  • Q: "실제 운영체제는 페이징과 세그멘테이션 중 주로 어떤 방식을 사용하나요?"
  • A: 현대 대부분 범용 OS(Linux, Windows, macOS 등)는 주로 페이징 기법을 핵심으로 사용합니다. 외부 단편화 해결과 가상 메모리 구현에 유리하기 때문입니다. x86-64 아키텍처에서는 세그멘테이션 기능이 축소되고 거의 페이징에 의존합니다.
  • Q: "페이지드 세그멘테이션은 장점만 있는 것 같은데 왜 널리 쓰이지 않나요?"
  • A: 가장 큰 이유는 복잡성입니다. 주소 변환 하드웨어와 관리 로직이 훨씬 복잡해집니다. 다중 레벨 페이징과 페이지 테이블의 부가 기능으로도 충분히 유연한 관리가 가능해지면서, 굳이 더 복잡한 방식을 사용할 필요성이 줄었습니다.

[마무리하며]

이번 글에서는 페이징 시스템의 성능과 보호 메커니즘, 대안적인 테이블 구조, 그리고 다른 메모리 관리 기법인 세그멘테이션에 대해 알아보았습니다. 페이징은 TLB를 통해 성능 문제를 완화하고, 보호 비트 등으로 메모리를 안전하게 관리하며, 공유 페이지를 통해 메모리를 절약합니다. 세그멘테이션은 의미 단위 관리에 장점이 있지만 외부 단편화 문제가 있습니다.

 

지금까지는 주로 물리 메모리 관리와 주소 변환 자체에 초점을 맞추었습니다. 다음 글에서는 이 기술들을 바탕으로 구현되는 현대 운영체제의 핵심 기능, 즉 물리 메모리 크기의 한계를 넘어 프로세스에게 훨씬 큰 가상 주소 공간을 제공하고 메모리를 더욱 효율적으로 사용하는 가상 메모리(Virtual Memory)와 요구 페이징(Demand Paging)에 대해 본격적으로 알아보겠습니다!