연속 메모리 할당 ⭐⭐
연속 메모리 할당 ⭐⭐¶
개요¶
연속 메모리 할당은 각 프로세스가 메모리에서 연속된 하나의 영역을 차지하는 메모리 관리 기법입니다. 고정 분할과 가변 분할 방식, 그리고 효율적인 메모리 배치 전략에 대해 학습합니다.
목차¶
- 메모리 분할 개요
- 고정 분할 (Fixed Partitioning)
- 가변 분할 (Variable Partitioning)
- 메모리 배치 전략
- 단편화 (Fragmentation)
- 압축 (Compaction)
- 연습 문제
1. 메모리 분할 개요¶
메모리 구조¶
┌─────────────────────────────────────────────────────────────┐
│ 전체 메모리 구조 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 낮은 주소 │
│ ┌──────────────────────────────────────────┐ │
│ │ 운영체제 (커널) │ 0x0000 │
│ │ 인터럽트 벡터, 드라이버, 커널 코드 │ │
│ ├──────────────────────────────────────────┤ │
│ │ │ │
│ │ │ │
│ │ 사용자 영역 │ │
│ │ (프로세스들이 사용) │ │
│ │ │ │
│ │ │ │
│ └──────────────────────────────────────────┘ 0xFFFF │
│ 높은 주소 │
│ │
└─────────────────────────────────────────────────────────────┘
단일 프로그래밍 vs 다중 프로그래밍¶
┌────────────────────────────────────────────────────────────────────┐
│ 단일 프로그래밍 다중 프로그래밍 │
├────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ OS │ │ OS │ │
│ ├──────────────┤ ├──────────────┤ │
│ │ │ │ 프로세스 1 │ │
│ │ 프로세스 │ ├──────────────┤ │
│ │ │ │ 프로세스 2 │ │
│ │ │ ├──────────────┤ │
│ ├──────────────┤ │ 프로세스 3 │ │
│ │ │ ├──────────────┤ │
│ │ 낭비 │ │ 빈 공간 │ │
│ │ │ │ │ │
│ └──────────────┘ └──────────────┘ │
│ │
│ - 한 번에 하나만 - 여러 프로세스 동시 적재 │
│ - 메모리 낭비 심함 - CPU 활용률 향상 │
│ │
└────────────────────────────────────────────────────────────────────┘
2. 고정 분할 (Fixed Partitioning)¶
2.1 개념¶
메모리를 고정된 크기의 파티션으로 미리 나누어 놓는 방식입니다.
┌─────────────────────────────────────────────────────────────┐
│ 고정 분할 (동일 크기) │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ OS │ 64KB │
│ ├──────────────────────────────────────────┤ │
│ │ 파티션 1 │ 64KB │
│ ├──────────────────────────────────────────┤ │
│ │ 파티션 2 │ 64KB │
│ ├──────────────────────────────────────────┤ │
│ │ 파티션 3 │ 64KB │
│ ├──────────────────────────────────────────┤ │
│ │ 파티션 4 │ 64KB │
│ └──────────────────────────────────────────┘ │
│ │
│ 특징: 모든 파티션이 같은 크기 (64KB) │
│ │
└─────────────────────────────────────────────────────────────┘
2.2 다양한 크기의 고정 분할¶
┌─────────────────────────────────────────────────────────────┐
│ 고정 분할 (다양한 크기) │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ OS │ 64KB │
│ ├──────────────────────────────────────────┤ │
│ │ 파티션 1 │ 32KB │
│ ├──────────────────────────────────────────┤ │
│ │ 파티션 2 │ 64KB │
│ ├──────────────────────────────────────────┤ │
│ │ │ │
│ │ 파티션 3 │ 128KB │
│ │ │ │
│ ├──────────────────────────────────────────┤ │
│ │ 파티션 4 │ 256KB │
│ │ │ │
│ │ │ │
│ └──────────────────────────────────────────┘ │
│ │
│ 장점: 다양한 크기의 프로세스 수용 가능 │
│ │
└─────────────────────────────────────────────────────────────┘
2.3 파티션 테이블¶
// 고정 분할 관리 구조체
typedef struct {
int partition_id;
int base_address;
int size;
int is_allocated; // 할당 여부
int process_id; // 할당된 프로세스 (-1이면 비어있음)
} Partition;
// 파티션 테이블 예시
Partition partition_table[] = {
{0, 0x10000, 32 * 1024, 1, 101}, // 32KB, 프로세스 101
{1, 0x18000, 64 * 1024, 1, 102}, // 64KB, 프로세스 102
{2, 0x28000, 128 * 1024, 0, -1}, // 128KB, 비어있음
{3, 0x48000, 256 * 1024, 1, 103} // 256KB, 프로세스 103
};
// 프로세스에 적합한 파티션 찾기
int find_partition(int process_size) {
for (int i = 0; i < NUM_PARTITIONS; i++) {
if (!partition_table[i].is_allocated &&
partition_table[i].size >= process_size) {
return i;
}
}
return -1; // 적합한 파티션 없음
}
2.4 고정 분할의 문제점¶
┌─────────────────────────────────────────────────────────────┐
│ 내부 단편화 발생 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 64KB 파티션에 45KB 프로세스 할당: │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ 프로세스 (45KB) │ 사용됨 │
│ ├──────────────────────────────────────────┤ │
│ │ 낭비 (19KB) │ 내부 단편화 │
│ └──────────────────────────────────────────┘ │
│ │
│ → 19KB가 낭비됨 (다른 프로세스가 사용 불가) │
│ │
└─────────────────────────────────────────────────────────────┘
3. 가변 분할 (Variable Partitioning)¶
3.1 개념¶
프로세스 크기에 맞게 파티션을 동적으로 생성하는 방식입니다.
┌─────────────────────────────────────────────────────────────┐
│ 가변 분할 예시 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 초기 상태: │
│ ┌──────────────────────────────────────────┐ 0 │
│ │ OS │ 64KB │
│ ├──────────────────────────────────────────┤ 64KB │
│ │ │ │
│ │ 자유 공간 │ │
│ │ (448KB) │ │
│ │ │ │
│ └──────────────────────────────────────────┘ 512KB │
│ │
│ P1(100KB), P2(50KB), P3(200KB) 적재 후: │
│ ┌──────────────────────────────────────────┐ 0 │
│ │ OS │ 64KB │
│ ├──────────────────────────────────────────┤ │
│ │ P1 (100KB) │ │
│ ├──────────────────────────────────────────┤ 164KB │
│ │ P2 (50KB) │ │
│ ├──────────────────────────────────────────┤ 214KB │
│ │ │ │
│ │ P3 (200KB) │ │
│ │ │ │
│ ├──────────────────────────────────────────┤ 414KB │
│ │ 자유 공간 (98KB) │ │
│ └──────────────────────────────────────────┘ 512KB │
│ │
└─────────────────────────────────────────────────────────────┘
3.2 홀(Hole) 관리¶
┌─────────────────────────────────────────────────────────────┐
│ P2 종료 후 메모리 상태 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ OS │ │
│ ├──────────────────────────────────────────┤ │
│ │ P1 (100KB) │ │
│ ├──────────────────────────────────────────┤ │
│ │ *** 홀 (50KB) *** │ ← 빈 공간 │
│ ├──────────────────────────────────────────┤ │
│ │ │ │
│ │ P3 (200KB) │ │
│ │ │ │
│ ├──────────────────────────────────────────┤ │
│ │ 자유 공간 (98KB) │ │
│ └──────────────────────────────────────────┘ │
│ │
│ 홀(Hole): 프로세스 사이에 생긴 빈 공간 │
│ 외부 단편화 발생! │
│ │
└─────────────────────────────────────────────────────────────┘
3.3 자유 공간 리스트¶
// 자유 공간 노드
typedef struct FreeBlock {
int start_address;
int size;
struct FreeBlock* next;
} FreeBlock;
// 자유 공간 리스트 예시
// 주소순으로 정렬
/*
[164KB, 50KB] -> [414KB, 98KB] -> NULL
홀 1 홀 2
*/
// 메모리 할당
FreeBlock* allocate_memory(FreeBlock** free_list, int size) {
FreeBlock* prev = NULL;
FreeBlock* current = *free_list;
while (current != NULL) {
if (current->size >= size) {
// 할당 가능!
int allocated_address = current->start_address;
if (current->size == size) {
// 정확히 맞으면 블록 제거
if (prev == NULL) {
*free_list = current->next;
} else {
prev->next = current->next;
}
free(current);
} else {
// 크면 분할
current->start_address += size;
current->size -= size;
}
return allocated_address;
}
prev = current;
current = current->next;
}
return NULL; // 할당 실패
}
// 메모리 해제 (인접 홀 병합)
void free_memory(FreeBlock** free_list, int address, int size) {
FreeBlock* new_block = malloc(sizeof(FreeBlock));
new_block->start_address = address;
new_block->size = size;
// 주소순으로 삽입
FreeBlock* prev = NULL;
FreeBlock* current = *free_list;
while (current != NULL && current->start_address < address) {
prev = current;
current = current->next;
}
new_block->next = current;
if (prev == NULL) {
*free_list = new_block;
} else {
prev->next = new_block;
}
// 인접 블록 병합
merge_adjacent_blocks(free_list);
}
4. 메모리 배치 전략¶
새 프로세스를 메모리의 어떤 홀에 배치할지 결정하는 전략입니다.
4.1 First-Fit (최초 적합)¶
┌─────────────────────────────────────────────────────────────┐
│ First-Fit 전략 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 자유 공간 리스트: │
│ [100KB] -> [500KB] -> [200KB] -> [300KB] │
│ │
│ 150KB 프로세스 할당 요청: │
│ │
│ 1. [100KB] 검사 → 150KB > 100KB → 불가 │
│ 2. [500KB] 검사 → 150KB <= 500KB → 여기에 할당! │
│ │
│ 결과: │
│ [100KB] -> [350KB] -> [200KB] -> [300KB] │
│ ↑ (500-150=350KB 남음) │
│ │
│ 장점: 검색 속도 빠름 │
│ 단점: 앞쪽에 작은 홀들이 모임 │
│ │
└─────────────────────────────────────────────────────────────┘
// First-Fit 구현
FreeBlock* first_fit(FreeBlock* free_list, int size) {
FreeBlock* current = free_list;
while (current != NULL) {
if (current->size >= size) {
return current; // 첫 번째 적합한 블록 반환
}
current = current->next;
}
return NULL;
}
4.2 Best-Fit (최적 적합)¶
┌─────────────────────────────────────────────────────────────┐
│ Best-Fit 전략 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 자유 공간 리스트: │
│ [100KB] -> [500KB] -> [200KB] -> [300KB] │
│ │
│ 150KB 프로세스 할당 요청: │
│ │
│ 전체 검색: │
│ - [100KB]: 불가 (100 < 150) │
│ - [500KB]: 가능, 남음 = 350KB │
│ - [200KB]: 가능, 남음 = 50KB ← 가장 적게 남음! │
│ - [300KB]: 가능, 남음 = 150KB │
│ │
│ 200KB 블록에 할당! │
│ │
│ 결과: │
│ [100KB] -> [500KB] -> [50KB] -> [300KB] │
│ │
│ 장점: 메모리 낭비 최소화 │
│ 단점: 전체 검색 필요, 아주 작은 홀 생성 │
│ │
└─────────────────────────────────────────────────────────────┘
// Best-Fit 구현
FreeBlock* best_fit(FreeBlock* free_list, int size) {
FreeBlock* best = NULL;
int min_diff = INT_MAX;
FreeBlock* current = free_list;
while (current != NULL) {
if (current->size >= size) {
int diff = current->size - size;
if (diff < min_diff) {
min_diff = diff;
best = current;
}
}
current = current->next;
}
return best;
}
4.3 Worst-Fit (최악 적합)¶
┌─────────────────────────────────────────────────────────────┐
│ Worst-Fit 전략 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 자유 공간 리스트: │
│ [100KB] -> [500KB] -> [200KB] -> [300KB] │
│ │
│ 150KB 프로세스 할당 요청: │
│ │
│ 가장 큰 블록 찾기: │
│ - [100KB], [500KB], [200KB], [300KB] │
│ - 최대: 500KB ← 여기에 할당! │
│ │
│ 결과: │
│ [100KB] -> [350KB] -> [200KB] -> [300KB] │
│ ↑ (큰 남은 공간 = 나중에 활용 가능) │
│ │
│ 장점: 남은 공간이 커서 다른 프로세스 수용 가능 │
│ 단점: 큰 프로세스 배치 어려움 │
│ │
└─────────────────────────────────────────────────────────────┘
// Worst-Fit 구현
FreeBlock* worst_fit(FreeBlock* free_list, int size) {
FreeBlock* worst = NULL;
int max_size = 0;
FreeBlock* current = free_list;
while (current != NULL) {
if (current->size >= size && current->size > max_size) {
max_size = current->size;
worst = current;
}
current = current->next;
}
return worst;
}
4.4 전략 비교¶
┌────────────────────────────────────────────────────────────────────┐
│ 메모리 배치 전략 비교 │
├──────────┬─────────────────┬─────────────────┬────────────────────┤
│ 전략 │ 검색 속도 │ 메모리 활용 │ 특징 │
├──────────┼─────────────────┼─────────────────┼────────────────────┤
│First-Fit │ O(n) │ 보통 │ 빠르고 간단 │
│ │ (평균적으로 │ │ 실무에서 가장 많이 │
│ │ 빨리 종료) │ │ 사용 │
├──────────┼─────────────────┼─────────────────┼────────────────────┤
│Best-Fit │ O(n) │ 좋음 │ 아주 작은 홀 생성 │
│ │ (전체 검색) │ │ 그 홀들은 활용 어려움│
├──────────┼─────────────────┼─────────────────┼────────────────────┤
│Worst-Fit │ O(n) │ 나쁨 │ 큰 홀 소모 │
│ │ (전체 검색) │ │ 거의 사용 안 함 │
├──────────┼─────────────────┼─────────────────┼────────────────────┤
│Next-Fit │ O(n) │ 보통 │ First-Fit 변형 │
│ │ │ │ 마지막 위치부터 │
└──────────┴─────────────────┴─────────────────┴────────────────────┘
4.5 Next-Fit¶
// Next-Fit 구현
FreeBlock* last_allocated = NULL; // 마지막 할당 위치 기억
FreeBlock* next_fit(FreeBlock* free_list, int size) {
// 마지막 할당 위치부터 시작
FreeBlock* start = (last_allocated != NULL) ? last_allocated : free_list;
FreeBlock* current = start;
do {
if (current->size >= size) {
last_allocated = current;
return current;
}
current = current->next;
if (current == NULL) {
current = free_list; // 처음으로 돌아감
}
} while (current != start);
return NULL;
}
5. 단편화 (Fragmentation)¶
5.1 내부 단편화 (Internal Fragmentation)¶
┌─────────────────────────────────────────────────────────────┐
│ 내부 단편화 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 고정 분할 또는 페이징에서 발생: │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ │ │
│ │ 할당된 블록 (예: 4KB 페이지) │ │
│ │ │ │
│ │ ┌────────────────────────┐ │ │
│ │ │ 프로세스 데이터 (3KB) │ │ │
│ │ ├────────────────────────┤ │ │
│ │ │ 내부 단편화 (1KB) │ ← 낭비! │ │
│ │ └────────────────────────┘ │ │
│ │ │ │
│ └──────────────────────────────────────────┘ │
│ │
│ 특징: │
│ - 할당된 블록 내부의 낭비 │
│ - 다른 프로세스가 사용 불가 │
│ - 고정 분할, 페이징에서 발생 │
│ │
└─────────────────────────────────────────────────────────────┘
5.2 외부 단편화 (External Fragmentation)¶
┌─────────────────────────────────────────────────────────────┐
│ 외부 단편화 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 가변 분할에서 발생: │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ OS │ │
│ ├──────────────────────────────────────────┤ │
│ │ P1 (100KB) │ │
│ ├──────────────────────────────────────────┤ │
│ │ *** 홀 (30KB) *** │ ← 작은 홀 │
│ ├──────────────────────────────────────────┤ │
│ │ P2 (200KB) │ │
│ ├──────────────────────────────────────────┤ │
│ │ *** 홀 (25KB) *** │ ← 작은 홀 │
│ ├──────────────────────────────────────────┤ │
│ │ P3 (150KB) │ │
│ ├──────────────────────────────────────────┤ │
│ │ *** 홀 (45KB) *** │ ← 작은 홀 │
│ └──────────────────────────────────────────┘ │
│ │
│ 총 자유 공간: 30 + 25 + 45 = 100KB │
│ 그러나 50KB 프로세스도 적재 불가! (연속 공간 없음) │
│ │
└─────────────────────────────────────────────────────────────┘
5.3 50% 규칙 (50-percent Rule)¶
통계적으로, N개의 할당 블록이 있을 때 약 0.5N개의 홀이 생성됩니다. 즉, 메모리의 1/3이 단편화로 손실될 수 있습니다.
메모리 = 할당 블록 + 홀
N개의 할당 블록 → 약 0.5N개의 홀
손실률 = 홀 / (할당블록 + 홀) = 0.5N / (N + 0.5N) = 1/3 ≈ 33%
6. 압축 (Compaction)¶
6.1 개념¶
외부 단편화를 해결하기 위해 모든 프로세스를 한쪽으로 밀어 큰 연속 공간을 만드는 것입니다.
┌─────────────────────────────────────────────────────────────┐
│ 압축 과정 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 압축 전: 압축 후: │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ OS │ │ OS │ │
│ ├──────────────┤ ├──────────────┤ │
│ │ P1 (100KB) │ │ P1 (100KB) │ │
│ ├──────────────┤ ├──────────────┤ │
│ │ 홀 (30KB) │ ────▶ │ P2 (200KB) │ │
│ ├──────────────┤ │ │ │
│ │ P2 (200KB) │ ├──────────────┤ │
│ │ │ │ P3 (150KB) │ │
│ ├──────────────┤ │ │ │
│ │ 홀 (25KB) │ ├──────────────┤ │
│ ├──────────────┤ │ │ │
│ │ P3 (150KB) │ │ 홀 (100KB) │ │
│ │ │ │ (연속!) │ │
│ ├──────────────┤ │ │ │
│ │ 홀 (45KB) │ │ │ │
│ └──────────────┘ └──────────────┘ │
│ │
│ 총 홀: 100KB 총 홀: 100KB (연속) │
│ (흩어져 있음) 새 프로세스 적재 가능! │
│ │
└─────────────────────────────────────────────────────────────┘
6.2 압축의 제약¶
┌─────────────────────────────────────────────────────────────┐
│ 압축의 문제점 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 실행 시간 바인딩 필요 │
│ - 프로세스 이동 후 주소가 변경됨 │
│ - 컴파일/로드 시간 바인딩에서는 불가 │
│ │
│ 2. 높은 비용 │
│ - 프로세스를 메모리에서 복사해야 함 │
│ - 시스템 일시 중단 필요 │
│ │
│ 3. 최적 압축 전략 결정이 어려움 │
│ │
│ 전략 1: 모든 프로세스를 맨 아래로 │
│ → 이동량 최대 │
│ │
│ 전략 2: 일부만 이동하여 홀 병합 │
│ → NP-완전 문제 (최적해 찾기 어려움) │
│ │
└─────────────────────────────────────────────────────────────┘
6.3 압축 알고리즘 예시¶
// 단순 압축 알고리즘 (모든 프로세스를 아래로)
void compact_memory(Process* processes[], int n, int os_end) {
int next_address = os_end; // OS 바로 다음부터 시작
for (int i = 0; i < n; i++) {
if (processes[i]->is_active) {
if (processes[i]->base != next_address) {
// 프로세스 이동
printf("P%d: %d -> %d (크기: %d)\n",
processes[i]->pid,
processes[i]->base,
next_address,
processes[i]->size);
// 메모리 복사 (실제로는 memcpy)
move_memory(processes[i]->base, next_address,
processes[i]->size);
// 새 주소 업데이트
processes[i]->base = next_address;
// MMU 재배치 레지스터 갱신
update_mmu(processes[i]->pid, next_address);
}
next_address += processes[i]->size;
}
}
// 남은 공간은 하나의 큰 홀
printf("자유 공간: %d부터 끝까지\n", next_address);
}
연습 문제¶
문제 1: 메모리 배치 전략¶
다음 자유 공간 리스트가 있을 때 120KB 프로세스를 할당할 경우 각 전략이 선택하는 홀을 구하시오.
자유 공간: [150KB] -> [200KB] -> [120KB] -> [180KB]
정답 보기
- **First-Fit**: 150KB 홀 (첫 번째로 120KB 이상) - **Best-Fit**: 120KB 홀 (정확히 맞음, 남는 공간 0) - **Worst-Fit**: 200KB 홀 (가장 큼, 남는 공간 80KB)문제 2: 단편화 계산¶
256KB 파티션에 다음 프로세스들이 순서대로 할당됩니다. 내부 단편화의 총량을 계산하시오.
- 프로세스 1: 50KB
- 프로세스 2: 80KB
- 프로세스 3: 100KB
- 프로세스 4: 20KB
정답 보기
고정 분할(256KB)에 각각 할당하는 경우: - P1: 256 - 50 = 206KB 낭비 - P2: 256 - 80 = 176KB 낭비 - P3: 256 - 100 = 156KB 낭비 - P4: 256 - 20 = 236KB 낭비 총 내부 단편화: 206 + 176 + 156 + 236 = 774KB (참고: 가변 분할에서는 내부 단편화가 0)문제 3: 가변 분할 시뮬레이션¶
1MB(1024KB) 메모리에서 OS가 100KB를 사용합니다. 다음 순서로 프로세스가 도착/종료할 때 First-Fit을 사용한 메모리 상태를 그리시오.
- P1(200KB) 도착
- P2(350KB) 도착
- P3(150KB) 도착
- P2 종료
- P4(80KB) 도착
- P5(300KB) 도착
정답 보기
1. P1 도착 후:
[OS:100KB][P1:200KB][Free:724KB]
2. P2 도착 후:
[OS:100KB][P1:200KB][P2:350KB][Free:374KB]
3. P3 도착 후:
[OS:100KB][P1:200KB][P2:350KB][P3:150KB][Free:224KB]
4. P2 종료 후:
[OS:100KB][P1:200KB][Hole:350KB][P3:150KB][Free:224KB]
5. P4(80KB) 도착 - First-Fit으로 350KB 홀 선택:
[OS:100KB][P1:200KB][P4:80KB][Hole:270KB][P3:150KB][Free:224KB]
6. P5(300KB) 도착 - 270KB 홀 불가, 224KB Free 불가
→ 할당 실패! (외부 단편화: 270+224=494KB 있지만 연속 300KB 없음)
문제 4: 압축 비용¶
위 문제 3의 상태 6에서 압축을 수행하면: 1. 이동해야 하는 프로세스는? 2. 압축 후 자유 공간 크기는? 3. P5를 적재할 수 있는가?
정답 보기
1. 이동할 프로세스: - P4: 380KB → 300KB 위치로 이동 - P3: 650KB → 380KB 위치로 이동 2. 압축 후: [OS:100KB][P1:200KB][P4:80KB][P3:150KB][Free:494KB] 자유 공간 = 1024 - 100 - 200 - 80 - 150 = 494KB 3. 494KB >= 300KB이므로 P5 적재 가능!문제 5: 전략 설계¶
다음 상황에서 어떤 배치 전략이 적합한지 설명하시오.
- 임베디드 시스템에서 빠른 응답 시간이 필요한 경우
- 메모리가 부족하고 최대한 많은 프로세스를 적재해야 하는 경우
- 주기적으로 비슷한 크기의 프로세스가 생성/종료되는 경우
정답 보기
1. **First-Fit** - 가장 빠른 검색 속도, 첫 번째 적합한 홀을 즉시 선택 2. **Best-Fit** - 메모리 낭비를 최소화하여 더 많은 프로세스 수용 가능 (단, 아주 작은 홀이 많이 생길 수 있음) 3. **Next-Fit** - 마지막 할당 위치부터 검색하여 메모리 전체에 균등하게 홀이 분포되도록 함. 특정 영역에 집중되는 것 방지다음 단계¶
12_Paging.md에서 연속 할당의 단편화 문제를 해결하는 페이징 기법을 배워봅시다!
참고 자료¶
- Silberschatz, "Operating System Concepts" Chapter 8
- Tanenbaum, "Modern Operating Systems" Chapter 3
- Knuth, "The Art of Computer Programming" - 동적 메모리 할당 알고리즘