임베디드기사 실기 20부작 11편
Best-Fit, Paging, Segmentation, Thrashing, Working Set으로 이해하는 Memory Management
지난 10편에서는 SRAM과 DRAM의 구조적 차이, Refresh, Cache와 Main Memory의 역할을 살펴보았습니다. 이번 11편에서는 한 단계 더 들어가 운영체제가 제한된 메모리를 어떻게 나누고, 주소를 변환하고, 부족한 메모리를 어떻게 버티며, 반대로 메모리 관리가 실패했을 때 왜 시스템 전체가 느려지는지 살펴보겠습니다.
하나의 프로그램만 실행하는 단순한 시스템에서는 메모리를 거의 직접 배치해도 됩니다. 그러나 Linux 같은 운영체제에서는 여러 프로세스가 동시에 실행되고, 각 프로세스는 자신만의 코드, 데이터, 힙, 스택을 사용합니다. 이때 운영체제는 프로세스마다 독립된 주소 공간을 제공하고, 실제 RAM의 어느 위치에 데이터를 둘지 결정하며, 더 이상 필요 없는 공간을 회수해야 합니다.
결국 메모리 관리는 단순한 “빈 공간 찾기”가 아니라 다음 세 가지 문제를 동시에 해결하는 일입니다.
- 어디에 배치할 것인가?
- 가상 주소를 실제 물리 주소와 어떻게 연결할 것인가?
- RAM이 부족할 때 어떤 데이터를 내보내고 어떤 데이터를 남길 것인가?
먼저 가장 직관적인 방식부터 시작해 보겠습니다. 빈 메모리 블록이 여러 개 있을 때 새로운 프로세스나 데이터가 들어갈 공간을 선택해야 합니다. 이때 대표적인 방식이 First-Fit, Best-Fit, Worst-Fit입니다.
First-Fit은 앞에서부터 찾다가 필요한 크기 이상인 첫 번째 빈 공간에 할당합니다. 탐색 속도가 빠른 것이 장점입니다.
Best-Fit은 요청 크기 이상인 빈 공간 중에서 요청 크기와 가장 가까운 공간을 선택합니다. 예를 들어 10K, 20K, 14K, 30K의 빈 블록이 있고 15K가 필요하다면 15K 이상인 후보는 20K와 30K입니다. 이 가운데 남는 공간이 가장 작은 20K 블록을 선택합니다. 결과적으로 5K가 남습니다.
Worst-Fit은 가장 큰 빈 공간을 선택합니다. 큰 공간을 쪼개어 비교적 큰 잔여 공간을 남기려는 방식입니다.
시험에서는 “15K를 할당할 때 Best-Fit은 어디를 선택하는가?”처럼 계산형 또는 개념형으로 출제될 수 있습니다. 핵심 문장은 간단합니다.
Best-Fit은 요청 크기 이상인 가용 블록 중 남는 공간이 가장 작은 블록을 선택한다.
연속 메모리 할당에서는 시간이 지날수록 메모리 곳곳에 작은 빈 공간이 생길 수 있습니다. 전체 빈 공간을 합치면 충분한데도 하나의 큰 연속 공간이 없어 할당하지 못하는 현상이 발생합니다. 이를 외부 단편화(External Fragmentation)라고 합니다.
반대로 일정한 크기의 블록을 할당했는데 실제로 사용하지 않는 공간이 블록 내부에 남는 현상은 내부 단편화(Internal Fragmentation)입니다. Paging에서는 페이지 크기보다 작은 데이터가 마지막 페이지에 들어갈 때 내부 단편화가 발생할 수 있습니다.
Paging은 가상 메모리 공간을 일정한 크기의 Page로 나누고, 물리 메모리는 같은 크기의 Frame으로 나누는 방식입니다. 한 프로세스의 페이지들은 물리 메모리에서 반드시 연속적으로 존재할 필요가 없습니다.
예를 들어 가상 주소 공간의 Page 0은 물리 Frame 7에, Page 1은 Frame 2에, Page 2는 Frame 15에 위치할 수 있습니다. 이 연결 관계는 Page Table이 관리합니다.
CPU가 만든 가상 주소는 MMU를 통해 Page Number와 Offset으로 해석되고, Page Table을 참조하여 실제 Frame Number를 찾은 뒤 물리 주소로 변환됩니다.
가상 주소 = Page Number + Offset
물리 주소 = Frame Number + Offset
Paging의 장점은 프로세스를 물리 메모리의 연속된 공간에 배치할 필요가 없다는 점입니다. 따라서 연속 할당에서 문제가 되었던 외부 단편화를 크게 줄일 수 있습니다.
Segmentation은 메모리를 동일한 크기로 나누지 않고 프로그램의 논리적인 의미 단위로 나눕니다. 예를 들어 Code Segment, Data Segment, Stack Segment처럼 각 영역의 역할에 따라 크기가 달라질 수 있습니다.
주소는 일반적으로 Segment Number + Offset 구조로 이해할 수 있습니다. Segment Table에는 각 Segment의 Base Address와 Limit가 저장됩니다. Base는 해당 Segment가 실제 메모리 어디에서 시작하는지를, Limit는 Segment의 크기 범위를 나타냅니다.
Paging이 “고정 크기 단위”라면 Segmentation은 “논리적 의미 단위”라는 차이를 기억하면 실기 답안 작성이 쉬워집니다.
| 항목 | Paging | Segmentation |
|---|---|---|
| 분할 기준 | 고정 크기 | 논리적 단위 |
| 주소 구조 | Page + Offset | Segment + Offset |
| 대표 문제 | 내부 단편화 | 외부 단편화 가능 |
가상 메모리는 실제 RAM보다 큰 주소 공간을 프로세스가 사용할 수 있도록 해 줍니다. 모든 페이지를 항상 RAM에 둘 필요는 없고, 현재 필요한 페이지를 중심으로 RAM에 올려 둡니다.
CPU가 접근한 Page가 RAM에 없을 때 Page Fault가 발생합니다. 운영체제는 해당 페이지를 저장장치의 Swap 영역이나 파일에서 읽어 RAM의 Frame으로 가져온 뒤 Page Table을 갱신하고 실행을 계속합니다.
Page Fault 자체는 가상 메모리 시스템에서 정상적으로 발생할 수 있는 사건입니다. 문제는 너무 자주 발생할 때입니다.
프로세스들이 실제로 필요로 하는 페이지보다 너무 적은 Frame만 할당받으면 Page Fault가 반복적으로 발생할 수 있습니다. 운영체제는 페이지를 RAM에 가져왔다가 다시 내보내는 작업을 계속하게 됩니다. 이처럼 실질적인 계산보다 Page 교체에 대부분의 시간을 사용하는 현상을 Thrashing이라고 합니다.
Thrashing이 발생하면 CPU 사용률이 오히려 낮아질 수 있습니다. CPU가 계산을 못해서가 아니라 필요한 데이터를 기다리느라 계속 멈추기 때문입니다. 시스템 전체 응답 시간이 급격히 나빠지고, 저장장치 I/O가 증가합니다.
Thrashing = 과도한 Page Fault와 Page 교체로 실제 작업보다 메모리 교체 작업에 더 많은 시간을 소비하는 현상
프로그램은 실행 중 모든 페이지를 동일하게 사용하지 않습니다. 특정 시간 구간에는 반복해서 접근하는 코드와 데이터가 있습니다. 이처럼 일정 시간 동안 프로세스가 활발하게 참조하는 페이지들의 집합을 Working Set이라고 합니다.
운영체제가 각 프로세스의 Working Set을 충분히 RAM에 유지할 수 있다면 Page Fault가 줄어듭니다. 반대로 Working Set보다 할당된 Frame이 지나치게 적으면 필요한 페이지가 계속 밀려나고 다시 들어오는 상황이 반복되면서 Thrashing으로 이어질 수 있습니다.
따라서 두 개념은 따로 외우기보다 다음처럼 연결해 이해하는 것이 좋습니다.
Working Set보다 메모리 할당량 부족 → Page Fault 증가 → Page 교체 증가 → Thrashing 가능성 증가
RAM에 빈 Frame이 없는데 새로운 Page를 올려야 한다면 어떤 기존 Page를 내보낼지 결정해야 합니다. 이것이 Page Replacement Algorithm입니다.
대표적으로 FIFO는 가장 먼저 들어온 페이지를 먼저 제거하고, LRU는 가장 오랫동안 사용되지 않은 페이지를 교체 대상으로 선택합니다. 시험에서는 알고리즘 이름 자체뿐 아니라 “왜 교체 알고리즘이 필요한가?”를 설명하도록 요구할 수 있습니다.
모범 답안은 다음 정도로 구성할 수 있습니다.
물리 메모리의 Frame이 부족할 때 새로운 Page를 적재하기 위해 기존 Page 중 하나를 선택해 교체해야 하며, 이를 결정하는 기법이 Page Replacement Algorithm이다.
PC나 Server에서는 수십 GB의 RAM이 일반적이지만 임베디드 장비는 메모리가 제한적인 경우가 많습니다. Vision Algorithm, Network Buffer, Logging, UI, Device Driver가 동시에 메모리를 사용하면 작은 누수도 장시간 운전 후 장애로 이어질 수 있습니다.
특히 생산 장비처럼 수일 또는 수주 동안 연속 운전하는 시스템에서는 다음 증상을 메모리 관점에서 의심할 수 있습니다.
- 시간이 지날수록 응답이 느려진다.
- 특정 기능을 반복하면 사용 가능 메모리가 계속 감소한다.
- OOM Killer가 발생한다.
- Swap I/O가 급증한다.
- 평소보다 Page Fault가 크게 늘어난다.
이때 단순히 “RAM이 부족하다”고 결론 내리지 말고 Process별 Memory 사용량, Heap 누수, Buffer 반환 여부, Driver Memory, Page Fault와 Swap 상태를 단계적으로 확인해야 합니다.
문제 1. 10K, 20K, 14K, 30K의 가용 블록이 있다. 15K 메모리를 Best-Fit으로 할당할 때 선택되는 블록은?
답: 20K. 15K 이상인 블록 중 요청 크기와 차이가 가장 작기 때문이다.
문제 2. Paging과 Segmentation의 차이를 설명하시오.
답: Paging은 가상 메모리를 동일한 크기의 Page로 나누고 물리 메모리를 Frame 단위로 관리한다. Segmentation은 Code, Data, Stack 등 프로그램의 논리적 의미 단위로 가변 크기 영역을 나눈다.
문제 3. Thrashing을 설명하시오.
답: 메모리 부족으로 Page Fault가 지나치게 많이 발생하여 CPU가 실제 작업보다 Page 교체와 I/O 대기에 더 많은 시간을 사용하는 현상이다.
문제 4. Working Set의 의미와 목적을 설명하시오.
답: Working Set은 일정 시간 동안 프로세스가 집중적으로 참조하는 Page들의 집합이다. 이를 충분히 메모리에 유지하면 Page Fault를 줄이고 Thrashing을 방지하는 데 도움이 된다.
Best-Fit = 들어갈 수 있는 블록 중 가장 작은 것
Paging = 고정 크기 Page / Frame
Segmentation = 논리적 가변 크기 영역
Page Fault = 필요한 Page가 RAM에 없음
Thrashing = Page 교체만 반복해 성능 급락
Working Set = 최근 자주 사용하는 Page 집합
메모리 관리 문제는 용어가 많아 처음에는 각각 따로 외우기 쉽습니다. 그러나 실제로는 하나의 흐름으로 연결됩니다. 운영체제는 빈 공간을 선택하고, 가상 주소를 물리 주소로 변환하며, 필요한 Page를 RAM에 유지합니다. 메모리가 부족해지면 Page 교체가 발생하고, 이 작업이 지나치게 많아지면 Thrashing으로 이어집니다. Working Set은 이런 문제를 이해하는 핵심 개념입니다.
이번 편까지 이해했다면 “메모리는 단순한 저장 공간이 아니라 운영체제가 계속 배치·변환·교체·회수하는 동적 자원”이라는 관점을 잡으신 것입니다.
다음 12편 예고: ZONE_NORMAL, MTD, JFFS2, Btrfs, MBR - Linux 저장장치와 파일시스템의 구조
#임베디드기사 #임베디드기사실기 #임베디드시스템 #메모리관리 #BestFit #Paging #Segmentation #Thrashing #WorkingSet #PageFault #가상메모리 #운영체제 #LinuxKernel #페이지교체 #LRU #메모리단편화 #임베디드리눅스 #자격증공부 #기출문제 #실기시험