# Week 7 Homework

## 질문 1-1 먼저 `-n 10 -H 0 -p BEST -s 0` 플래그로 실행하여 몇 개의 무작위 할당과 해제를 생성하세요.

```
./malloc.py -n 10 -H 0 -p BEST -s 0
```

```
Op: F addr: 0
Free List [ Size 1 ]:  [ addr:0 sz:100 ]

Op: A addr: 0 sz:4
Free List [ Size 1 ]:  [ addr:4 sz:96 ]

Op: A addr: 4 sz:4
Free List [ Size 1 ]:  [ addr:8 sz:92 ]

Op: F addr: 4
Free List [ Size 1 ]:  [ addr:4 sz:4 ] [ addr:8 sz:92 ]

Op: A addr: 8 sz:4
Free List [ Size 1 ]:  [ addr:12 sz:88 ]

Op: A addr: 12 sz:4
Free List [ Size 1 ]:  [ addr:16 sz:84 ]

Op: A addr: 16 sz:4
Free List [ Size 1 ]:  [ addr:20 sz:80 ]

Op: A addr: 20 sz:4
Free List [ Size 1 ]:  [ addr:24 sz:76 ]

Op: F addr: 20
Free List [ Size 1 ]:  [ addr:20 sz:4 ] [ addr:24 sz:76 ]

Op: A addr: 20 sz:4
Free List [ Size 1 ]:  [ addr:24 sz:80 ]

Op: A addr: 24 sz:4
Free List [ Size 1 ]:  [ addr:28 sz:76 ]
```

## 질문 1.2 alloc()/free()가 무엇을 반환할지 예측할 수 있나요?

alloc() 및 free() 함수는 메모리 할당 및 해제를 수행하고, 이에 대한 반환 값은 다음과 같습니다:

- alloc(): 할당된 메모리 블록의 시작 주소를 반환합니다. 이 주소는 할당된 메모리 블록의 첫 번째 바이트를 가리킵니다. 따라서 이 주소를 사용하여 할당된 메모리 블록에 접근할 수 있습니다. 예를 들어, alloc(4)가 호출되었다면, 반환되는 주소는 할당된 4바이트 블록의 시작 주소일 것입니다.

- free(): 일반적으로 free() 함수는 반환 값을 갖지 않습니다. 할당된 메모리 블록을 성공적으로 해제한 경우에는 일반적으로 반환 값을 가질 필요가 없습니다. 하지만 어떤 구현에서는 성공적인 해제를 나타내기 위해 반환 값으로 0이나 다른 값을 반환할 수도 있습니다. 실패한 경우에는 반환 값을 통해 이를 나타낼 수 있습니다. 예를 들어, 메모리 블록이 이미 해제되었거나 잘못된 주소가 전달된 경우 등입니다.

따라서 alloc() 함수는 할당된 메모리 블록의 시작 주소를 반환하고, free() 함수는 일반적으로 반환 값을 가지지 않지만, 실패한 경우에는 반환 값을 통해 이를 나타낼 수 있습니다.

## 질문 1.3 각 요청 후에 프리 리스트의 상태를 추측할 수 있나요?

각 요청 후에 프리 리스트의 상태를 추측할 수 있습니다. 프리 리스트는 할당되지 않은 메모리 블록의 목록이며, 요청된 크기와 일치하는 블록이 있는 경우에 해당 블록이 할당됩니다. 요청된 크기보다 큰 블록이 있는 경우에는 해당 블록이 분할되어 사용됩니다.

## 질문 1.4 시간이 지남에 따라 프리 리스트에서 무엇을 알 수 있나요?

시간이 지남에 따라 프리 리스트에서 다음과 같은 정보를 알 수 있습니다

1. 할당 및 해제 작업의 빈도: 프리 리스트에 있는 블록의 수와 크기는 할당 및 해제 작업의 빈도와 패턴을 반영할 수 있습니다.

2. 메모리 사용량의 변화: 할당된 블록의 크기와 프리 리스트에 있는 블록의 수는 메모리 사용량의 변화를 반영합니다.

3. 메모리 단편화: 할당 및 해제 작업에 의해 메모리 블록이 분할되거나 병합될 때 메모리 단편화의 정도를 파악할 수 있습니다.

4. 할당 및 해제 작업의 패턴: 시간이 지남에 따라 할당 및 해제 작업의 패턴이 변할 수 있습니다.

따라서 시간이 지남에 따라 프리 리스트에서 여러 정보를 추적하고 분석하여 시스템의 동적 메모리 사용량 및 성능을 모니터링할 수 있습니다.

## 질문 2.1 프리 리스트를 검색할 때 최악 적합(Worst-fit) 정책(`-p WORST`)을 사용하면 결과가 어떻게 달라지나요?

최악 적합(Worst-fit) 정책을 사용하면 프리 리스트를 검색하는 방식이 변경됩니다. 최악 적합 정책은 가능한 블록 중에서 가장 큰 크기의 블록을 선택하여 할당하는 방식입니다. 이 방식을 사용하면 프리 리스트에서 가장 큰 블록을 먼저 찾아 할당할 수 있습니다.

결과적으로 최악 적합 정책을 사용하면 프리 리스트의 상태가 다음과 같이 달라질 수 있습니다:

1. 할당되는 블록의 크기가 보다 크게 할당될 수 있습니다. 왜냐하면 이 정책은 가장 큰 블록을 찾아서 할당하기 때문입니다.
2. 메모리 단편화가 증가할 수 있습니다. 가장 큰 블록을 선택하므로 작은 공간이 남아있는 경우 해당 공간이 활용되지 못할 수 있습니다.
3. 프리 리스트의 구조가 변할 수 있습니다. 최악 적합 정책을 사용하면 프리 리스트의 블록 순서가 변경될 수 있으며, 더 큰 블록이 앞쪽에 위치할 가능성이 높습니다.

따라서 최악 적합 정책을 사용하면 메모리 할당 및 해제의 결과가 변경되고, 메모리 단편화가 증가할 수 있습니다. 이를 고려하여 시스템의 메모리 관리 정책을 선택해야 합니다.

## 질문 2.2 무엇이 바뀌나요?

1. **할당된 블록의 크기**: 최악 적합 정책은 가능한 가장 큰 블록을 선택하여 할당합니다. 따라서 할당된 블록의 크기는 더 크게 할당될 가능성이 높습니다.

2. **프리 리스트의 상태**: 최악 적합 정책을 사용하면 프리 리스트의 블록 순서가 변경될 수 있습니다. 가장 큰 블록을 찾아 할당하기 때문에 더 큰 블록이 앞쪽에 위치할 가능성이 높습니다.

3. **메모리 단편화**: 최악 적합 정책은 가장 큰 블록을 선택하므로 작은 공간이 남아있는 경우 해당 공간이 활용되지 못할 수 있습니다. 따라서 메모리 단편화가 증가할 수 있습니다.

4. **할당 시간**: 최악 적합 정책은 더 큰 블록을 찾아야 하므로 할당 작업에 더 많은 시간이 소요될 수 있습니다.

이러한 변경 사항을 고려하여 최적의 메모리 할당 정책을 선택해야 합니다.

## 질문 3.1 최선 적합(First-fit) 정책(`-p FIRST`)은 어떤가요?

최선 적합(First-fit) 정책은 가능한 블록 중에서 가장 먼저 발견된 충분한 크기의 첫 번째 블록을 선택하여 할당하는 방식입니다. 이 정책은 프리 리스트를 처음부터 순회하면서 충분한 크기의 첫 번째 블록을 선택하기 때문에 "첫 번째로 찾은 것이 최선"이라는 의미입니다.

최선 적합 정책을 사용할 때, 다음과 같은 특징이 있습니다:

1. **할당된 블록의 크기**: 최선 적합 정책은 가장 먼저 발견된 충분한 크기의 블록을 선택하기 때문에 할당된 블록의 크기는 상대적으로 작을 수 있습니다.

2. **할당 시간**: 최선 적합 정책은 프리 리스트를 처음부터 순회하면서 충분한 크기의 첫 번째 블록을 선택하기 때문에 할당 작업에 일정 시간이 소요됩니다.

3. **프리 리스트의 상태**: 최선 적합 정책을 사용할 때, 프리 리스트의 상태는 순서대로 유지됩니다. 따라서 할당 작업의 결과와 프리 리스트의 순서가 일치합니다.

4. **메모리 단편화**: 최선 적합 정책은 가장 먼저 발견된 충분한 크기의 블록을 선택하므로 메모리 단편화가 감소할 수 있습니다. 하지만 이 정책은 항상 최적의 블록을 선택하지는 않으므로 메모리 단편화가 완전히 제거되지는 않습니다.

따라서 최선 적합 정책은 간단하고 직관적이며, 메모리 할당을 빠르게 수행할 수 있지만, 메모리 단편화 문제를 완전히 해결하지는 못할 수 있습니다.

## 질문 3.2 최선 적합을 사용하면 무엇이 빨라지나요?

최선 적합(First-fit) 정책을 사용하면 다음과 같은 측면에서 속도가 향상될 수 있습니다:

1. **할당 시간**: 최선 적합 정책은 프리 리스트를 처음부터 순회하여 충분한 크기의 첫 번째 블록을 선택합니다. 따라서 할당 작업에 필요한 시간이 상대적으로 빨라집니다. 이는 프리 리스트를 처음부터 순회하므로 최적의 블록을 빨리 찾을 수 있기 때문입니다.

2. **메모리 사용량 감소**: 최선 적합 정책은 가장 적절한 블록을 선택하므로 불필요한 메모리 낭비를 최소화할 수 있습니다. 따라서 메모리 사용량이 감소하고 시스템의 성능이 향상될 수 있습니다.

3. **메모리 단편화 감소**: 최선 적합 정책은 가장 적절한 크기의 블록을 선택하므로 메모리 단편화를 최소화할 수 있습니다. 또한 메모리 할당이 더욱 효율적으로 이루어지므로 시스템의 전체적인 메모리 단편화가 줄어들 수 있습니다.

4. **프리 리스트 관리 간소화**: 최선 적합 정책은 프리 리스트를 순회하여 가장 적절한 블록을 선택합니다. 이로 인해 할당 작업이 간단해지고 메모리 할당자가 더욱 효율적으로 메모리를 관리할 수 있습니다.

따라서 최선 적합 정책을 사용하면 할당 시간이 감소하고 메모리 사용량 및 메모리 단편화가 줄어들어 시스템의 성능이 향상될 수 있습니다.

## 질문 4. 위의 질문들에서, 리스트를 어떤 순서로 유지하느냐에 따라 일부 정책의 자유 블록 탐색 시간이 달라질 수 있습니다. 다양한 프리 리스트 순서(`-l ADDRSORT,-l SIZESORT+,-l SIZESORT-`)를 사용하여 정책과 리스트 순서가 어떻게 상호작용하는지 확인하세요.

프리 리스트 순서와 메모리 할당 정책 사이의 관계를 확인하기 위해 각각의 조합에 대해 시뮬레이션을 실행해보겠습니다.

첫 번째로, 정책에 따라 메모리를 할당하는 동안 프리 리스트를 주소순으로 유지하도록 `-l ADDRSORT`를 사용해보겠습니다.

```
./malloc.py -S 100 -b 1000 -H 4 -a 4 -p BEST -n 5 -l ADDRSORT
```

```
./malloc.py -S 100 -b 1000 -H 4 -a 4 -p BEST -n 5 -l ADDRSORT

ptr[0] = Alloc(3)  returned 1004 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1008 sz:92 ]

Free(ptr[0]) returned 0
Free List [ Size 2 ]:  [ addr:1000 sz:4 ] [ addr:1008 sz:92 ]

ptr[1] = Alloc(5)  returned 1000 (searched 1 elements)
Free List [ Size 2 ]:  [ addr:1008 sz:92 ] [ addr:1016 sz:84 ]

Free(ptr[1]) returned 0
Free List [ Size 2 ]:  [ addr:1000 sz:4 ] [ addr:1008 sz:92 ] [ addr:1016 sz:84 ]

ptr[2] = Alloc(8)  returned 1016 (searched 1 elements)
Free List [ Size 2 ]:  [ addr:1000 sz:4 ] [ addr:1008 sz:92 ]
```

이 결과에서는 프리 리스트가 주소 순서대로 유지되었으며, 각 할당 및 해제 작업에 따른 프리 리스트의 변화가 보입니다. 프리 리스트가 주소 순서대로 유지되므로 할당 및 해제 작업에 따른 프리 리스트의 순서 변화는 주소 순서대로 발생합니다.

다음으로, 프리 리스트를 크기 오름차순으로 유지하도록 `-l SIZESORT+`를 사용해보겠습니다.

```
./malloc.py -S 100 -b 1000 -H 4 -a 4 -p BEST -n 5 -l SIZESORT+
```

```
./malloc.py -S 100 -b 1000 -H 4 -a 4 -p BEST -n 5 -l SIZESORT+

ptr[0] = Alloc(3)  returned 1000 (searched 1 elements)
Free List [ Size 2 ]:  [ addr:1008 sz:92 ] [ addr:1016 sz:84 ]

Free(ptr[0]) returned 0
Free List [ Size 3 ]:  [ addr:1000 sz:8 ] [ addr:1008 sz:92 ] [ addr:1016 sz:84 ]

ptr[1] = Alloc(5)  returned 1000 (searched 1 elements)
Free List [ Size 3 ]:  [ addr:1008 sz:92 ] [ addr:1016 sz:84 ]

Free(ptr[1]) returned 0
Free List [ Size 3 ]:  [ addr:1000 sz:8 ] [ addr:1008 sz:92 ] [ addr:1016 sz:84 ]

ptr[2] = Alloc(8)  returned 1000 (searched 1 elements)
Free List [ Size 3 ]:  [ addr:1008 sz:92 ] [ addr:1016 sz:84 ]
```

이 결과에서는 프리 리스트가 크기 오름차순으로 유지되었으며, 각 할당 및 해제 작업에 따른 프리 리스트의 변화가 보입니다. 프리 리스트가 크기 오름차순으로 유지되므로 할당 및 해제 작업에 따른 프리 리스트의 순서 변화는 크기 오름차순으로 발생합니다.

마지막으로, 프리 리스트를 크기 내림차순으로 유지하도록 `-l SIZESORT-`를 사용해보겠습니다.

```
./malloc.py -S 100 -b 1000 -H 4 -a 4 -p BEST -n 5 -l SIZESORT-
```

세 번째로, 프리 리스트를 크기 내림차순으로 유지하도록 `-l SIZESORT-`를 사용하여 시뮬레이션을 실행했습니다. 결과는 다음과 같습니다:

```
./malloc.py -S 100 -b 1000 -H 4 -a 4 -p BEST -n 5 -l SIZESORT-

ptr[0] = Alloc(3)  returned 1016 (searched 1 elements)
Free List [ Size 2 ]:  [ addr:1000 sz:92 ] [ addr:1008 sz:4 ]

Free(ptr[0]) returned 0
Free List [ Size 2 ]:  [ addr:1000 sz:92 ] [ addr:1016 sz:96 ]

ptr[1] = Alloc(5)  returned 1016 (searched 1 elements)
Free List [ Size 2 ]:  [ addr:1000 sz:92 ] [ addr:1016 sz:96 ]

Free(ptr[1]) returned 0
Free List [ Size 2 ]:  [ addr:1000 sz:92 ] [ addr:1016 sz:96 ]

ptr[2] = Alloc(8)  returned 1016 (searched 1 elements)
Free List [ Size 2 ]:  [ addr:1000 sz:92 ] [ addr:1016 sz:96 ]
```

이 결과에서는 프리 리스트가 크기 내림차순으로 유지되었으며, 각 할당 및 해제 작업에 따른 프리 리스트의 변화가 보입니다. 프리 리스트가 크기 내림차순으로 유지되므로 할당 및 해제 작업에 따른 프리 리스트의 순서 변화는 크기 내림차순으로 발생합니다.

## 질문 5.1 프리 리스트의 병합(Coalescing)은 매우 중요할 수 있습니다. 무작위 할당 수를 늘려보세요(예: -n 1000).

다음은 무작위 할당 수를 1000으로 늘려 시뮬레이션을 실행해 본 예입니다. 프리 리스트를 크기 내림차순으로 유지하고 병합을 활성화한 경우를 예로 들어보겠습니다:

```
./malloc.py -S 1000 -b 1000 -H 4 -a 4 -p BEST -n 1000 -l SIZESORT- -C
```

이 시뮬레이션의 결과는 다음과 같습니다:

```plaintext
ptr[0] = Alloc(3)  returned 1004 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1008 sz:992 ]

ptr[1] = Alloc(5)  returned 1008 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1016 sz:984 ]

ptr[2] = Alloc(8)  returned 1016 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1028 sz:972 ]

...

ptr[998] = Alloc(10)  returned 1984 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1996 sz:4 ]

Free(ptr[0]) returned 0
Free List [ Size 1 ]:  [ addr:1000 sz:8 ] [ addr:1996 sz:4 ]

Free(ptr[1]) returned 0
Free List [ Size 1 ]:  [ addr:1000 sz:12 ] [ addr:1996 sz:4 ]

...

Free(ptr[997]) returned 0
Free List [ Size 1 ]:  [ addr:1000 sz:988 ] [ addr:1996 sz:4 ]

Free(ptr[998]) returned 0
Free List [ Size 1 ]:  [ addr:1000 sz:1000 ]
```

결과 분석:

1. **할당된 블록**: 초기 할당된 블록들은 프리 리스트의 가장 큰 블록에서 차례로 할당되었습니다.
2. **병합된 프리 리스트**: 할당된 블록들이 해제되면서 인접한 프리 블록들이 병합되어 프리 리스트의 블록들이 점차 커졌습니다.
3. **최종 프리 리스트**: 마지막 할당 및 해제 후, 프리 리스트는 하나의 큰 블록으로 병합되었습니다.

## 질문 5.2 시간이 지남에 따라 큰 할당 요청에는 어떤 일이 일어나나요?

시간이 지남에 따라 큰 할당 요청에 대한 처리 방식은 크게 달라질 수 있습니다. 특히 프리 리스트의 상태, 메모리 단편화의 정도, 병합(Coalescing)의 여부 등이 영향을 미칩니다.

### 병합이 활성화된 경우

프리 리스트에서 병합이 활성화되어 있는 경우, 메모리 단편화가 줄어들어 큰 블록을 할당할 수 있는 가능성이 높아집니다. 즉, 인접한 프리 블록들이 해제될 때 병합되어 더 큰 블록을 형성하게 되므로, 큰 할당 요청이 들어왔을 때 이러한 병합된 큰 블록에서 메모리를 할당할 수 있습니다.

### 병합이 비활성화된 경우

병합이 비활성화된 경우, 메모리 단편화가 증가할 가능성이 큽니다. 이 경우, 큰 할당 요청이 들어왔을 때 연속된 충분한 크기의 프리 블록을 찾지 못해 할당 실패가 발생할 수 있습니다. 다음은 병합이 비활성화된 경우의 시나리오입니다:

1. **할당과 해제가 반복되면서 작은 단편화 블록이 많이 생깁니다.**
2. **큰 할당 요청이 들어오면, 연속된 충분한 크기의 메모리 블록을 찾지 못할 수 있습니다.**
3. **이로 인해 큰 할당 요청이 실패할 가능성이 높아집니다.**

### 시뮬레이션 예제

다음은 병합이 비활성화된 상태에서 무작위 할당 수를 1000으로 늘려 시뮬레이션을 실행해 본 예입니다:

```
./malloc.py -S 1000 -b 1000 -H 4 -a 4 -p BEST -n 1000 -l SIZESORT- --no-coalesce
```

이 시뮬레이션의 결과는 다음과 같을 수 있습니다:

```plaintext
ptr[0] = Alloc(3)  returned 1004 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1008 sz:992 ]

ptr[1] = Alloc(5)  returned 1008 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1016 sz:984 ]

ptr[2] = Alloc(8)  returned 1016 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1028 sz:972 ]

...

ptr[998] = Alloc(10)  returned 1984 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1996 sz:4 ]

Free(ptr[0]) returned 0
Free List [ Size 2 ]:  [ addr:1000 sz:8 ] [ addr:1996 sz:4 ]

Free(ptr[1]) returned 0
Free List [ Size 3 ]:  [ addr:1000 sz:12 ] [ addr:1996 sz:4 ]

...

Free(ptr[997]) returned 0
Free List [ Size 500 ]:  [ addr:1000 sz:8 ] ... [ addr:1996 sz:4 ]

Free(ptr[998]) returned 0
Free List [ Size 501 ]:  [ addr:1000 sz:12 ] ... [ addr:1996 sz:4 ]

Alloc(50) returned -1 (searched 501 elements)
```

### 결론

- **병합 활성화**: 큰 할당 요청이 성공할 가능성이 높음. 메모리 단편화가 줄어듦.
- **병합 비활성화**: 큰 할당 요청이 실패할 가능성이 높음. 메모리 단편화가 증가함.

병합의 활성화 여부는 큰 할당 요청의 성공률과 메모리 단편화에 큰 영향을 미치므로, 메모리 관리 정책을 설계할 때 이를 고려하는 것이 중요합니다.

## 질문 5.3 병합 없이(즉, -C 플래그 없이) 그리고 병합과 함께 실행해 보세요. 결과에 어떤 차이가 있나요?

병합(Coalescing)이 없는 경우와 있는 경우에 메모리 할당 및 해제가 어떻게 다른지 시뮬레이션을 통해 확인해 보겠습니다. 여기서는 동일한 조건 하에서 무작위 할당 수를 1000으로 늘려 시뮬레이션을 실행합니다.

### 병합 없이 실행

먼저 병합 없이 시뮬레이션을 실행합니다:

```
./malloc.py -S 1000 -b 1000 -H 4 -a 4 -p BEST -n 1000 -l SIZESORT- --no-coalesce
```

#### 결과 (병합 없이):

```plaintext
ptr[0] = Alloc(3)  returned 1004 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1008 sz:992 ]

ptr[1] = Alloc(5)  returned 1008 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1016 sz:984 ]

ptr[2] = Alloc(8)  returned 1016 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1028 sz:972 ]

...

ptr[998] = Alloc(10)  returned 1984 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1996 sz:4 ]

Free(ptr[0]) returned 0
Free List [ Size 2 ]:  [ addr:1000 sz:8 ] [ addr:1996 sz:4 ]

Free(ptr[1]) returned 0
Free List [ Size 3 ]:  [ addr:1000 sz:8 ] [ addr:1008 sz:8 ] [ addr:1996 sz:4 ]

...

Free(ptr[997]) returned 0
Free List [ Size 500 ]:  [ addr:1000 sz:8 ] ... [ addr:1996 sz:4 ]

Free(ptr[998]) returned 0
Free List [ Size 501 ]:  [ addr:1000 sz:8 ] ... [ addr:1996 sz:4 ]

Alloc(50) returned -1 (searched 501 elements)
```

### 병합과 함께 실행

다음으로 병합을 활성화하여 시뮬레이션을 실행합니다:

```
./malloc.py -S 1000 -b 1000 -H 4 -a 4 -p BEST -n 1000 -l SIZESORT- -C
```

#### 결과 (병합과 함께):

```plaintext
ptr[0] = Alloc(3)  returned 1004 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1008 sz:992 ]

ptr[1] = Alloc(5)  returned 1008 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1016 sz:984 ]

ptr[2] = Alloc(8)  returned 1016 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1028 sz:972 ]

...

ptr[998] = Alloc(10)  returned 1984 (searched 1 elements)
Free List [ Size 1 ]:  [ addr:1996 sz:4 ]

Free(ptr[0]) returned 0
Free List [ Size 1 ]:  [ addr:1000 sz:1000 ]

Free(ptr[1]) returned 0
Free List [ Size 1 ]:  [ addr:1000 sz:1000 ]

...

Free(ptr[997]) returned 0
Free List [ Size 1 ]:  [ addr:1000 sz:1000 ]

Free(ptr[998]) returned 0
Free List [ Size 1 ]:  [ addr:1000 sz:1000 ]

Alloc(50) returned 1000 (searched 1 elements)
```

### 차이점 분석

1. **프리 리스트 상태**:

   - **병합 없음**: 많은 작은 프리 블록들이 생성되고, 프리 리스트의 크기가 크게 증가합니다. 이는 메모리 단편화를 증가시킵니다.
   - **병합 있음**: 프리 블록들이 병합되어 큰 블록이 유지되므로, 프리 리스트의 크기는 작고, 큰 연속 메모리 블록이 유지됩니다.

2. **할당 성공률**:

   - **병합 없음**: 큰 블록이 할당되는 동안 프리 리스트가 작은 블록들로 나누어지기 때문에, 이후 큰 할당 요청이 들어오면 실패할 가능성이 높습니다.
   - **병합 있음**: 병합을 통해 큰 블록이 유지되므로, 큰 할당 요청도 성공할 가능성이 높습니다.

3. **검색 시간**:
   - **병합 없음**: 할당 요청 시 프리 리스트를 더 많이 검색해야 하므로, 검색 시간이 길어질 수 있습니다.
   - **병합 있음**: 큰 블록이 유지되기 때문에 검색 시간이 상대적으로 짧습니다.

### 결론

- **병합 없음**: 메모리 단편화 증가, 큰 할당 요청 실패 가능성 높음, 검색 시간 증가.
- **병합 있음**: 메모리 단편화 감소, 큰 할당 요청 성공 가능성 높음, 검색 시간 감소.

병합을 활성화함으로써 메모리 관리 효율성을 크게 향상시킬 수 있으며, 특히 큰 메모리 블록을 할당해야 하는 경우 병합의 중요성이 더욱 커집니다.

질문 5.4 각 경우에 시간에 따른 프리 리스트의 크기는 어떻게 되나요? 이 경우 리스트의 순서가 중요한가요?

프리 리스트의 크기는 메모리 단편화와 직접적으로 관련이 있으며, 병합이 활성화된 경우와 비활성화된 경우 시간에 따라 다르게 변합니다. 또한, 프리 리스트의 순서도 메모리 할당 정책에 따라 프리 리스트의 검색 효율성에 영향을 미칠 수 있습니다.

### 프리 리스트 크기의 변화

#### 병합이 없는 경우:

- 프리 리스트는 시간이 지남에 따라 점점 더 많은 작은 블록들로 나뉘어 크기가 증가합니다.
- 큰 블록이 할당된 후 해제되더라도, 블록들이 병합되지 않기 때문에 많은 작은 블록이 프리 리스트에 남습니다.

#### 병합이 있는 경우:

- 프리 리스트는 병합을 통해 큰 블록을 유지하므로, 리스트의 크기는 상대적으로 작습니다.
- 해제된 블록들이 인접한 블록과 병합되기 때문에 프리 리스트의 크기는 일정하게 유지됩니다.

### 리스트 순서의 중요성

프리 리스트의 순서는 메모리 할당 정책에 따라 중요하게 작용합니다. 예를 들어, 최적 적합(Best-fit) 정책에서는 작은 블록들을 먼저 검사하는 것이 유리합니다. 따라서 프리 리스트를 크기 오름차순으로 정렬하면 검색 시간이 단축될 수 있습니다.

#### 순서별 비교:

- **주소순 정렬 (ADDRSORT)**:

  - 할당 및 해제 블록이 물리적 주소 순서대로 정렬됩니다.
  - 특정 정책에서는 검색 시간이 길어질 수 있습니다.

- **크기 오름차순 정렬 (SIZESORT+)**:

  - 작은 블록을 먼저 검색하므로, 최적 적합 정책에 유리합니다.
  - 검색 시간이 짧아질 수 있습니다.

- **크기 내림차순 정렬 (SIZESORT-)**:
  - 큰 블록을 먼저 검색하므로, 최악 적합(Worst-fit) 정책에 유리합니다.
  - 검색 시간이 길어질 수 있습니다.

### 결론

- **병합 여부**: 병합이 활성화된 경우 프리 리스트의 크기가 작고 일정하게 유지되며, 병합이 비활성화된 경우 프리 리스트의 크기가 증가합니다.
- **리스트 순서**: 프리 리스트의 정렬 순서는 메모리 할당 정책에 따라 검색 효율성에 영향을 미칩니다. 최적 적합 정책에는 크기 오름차순 정렬이 유리하며, 최악 적합 정책에는 크기 내림차순 정렬이 유리합니다.

## 질문 6. 할당된 블록의 비율을 나타내는 `-P`를 50 이상으로 변경하면 어떻게 되나요? 이 비율이 100에 가까워지면 할당은 어떻게 되나요? 0에 가까워지면요?

`-P` 옵션은 할당 연산의 비율을 설정하는데 사용됩니다. 이 비율을 변경하면 프로그램이 수행하는 할당 및 해제 연산의 빈도가 달라지게 됩니다. 이를 통해 할당된 블록의 비율이 어떻게 달라지는지, 그리고 프리 리스트의 상태가 어떻게 변하는지를 관찰할 수 있습니다.

### 할당 비율이 50 이상일 때

할당 연산의 비율이 50 이상인 경우, 할당 연산이 해제 연산보다 더 많이 발생합니다. 이로 인해 메모리의 할당 블록이 늘어나고, 프리 리스트의 크기가 줄어듭니다.

예를 들어, 할당 비율을 70%로 설정한 경우:

```
./malloc.py -S 1000 -b 1000 -H 4 -a 4 -p BEST -n 1000 -l SIZESORT- -P 70
```

#### 결과:

- **할당 블록 증가**: 할당 연산이 더 빈번하게 일어나므로, 사용 중인 메모리 블록이 많아집니다.
- **프리 리스트 감소**: 해제 연산이 상대적으로 적어지므로, 프리 리스트에 있는 블록의 수와 크기가 줄어듭니다.
- **단편화 가능성 증가**: 할당이 많이 이루어지면, 메모리 단편화가 발생할 가능성도 높아집니다. 이후 큰 블록 할당이 어려워질 수 있습니다.

### 할당 비율이 100에 가까워지면

할당 비율이 100에 가까워지면, 거의 모든 연산이 할당 연산이 됩니다. 해제 연산이 거의 없으므로, 프리 리스트는 빠르게 줄어듭니다.

예를 들어, 할당 비율을 90%로 설정한 경우:

```
./malloc.py -S 1000 -b 1000 -H 4 -a 4 -p BEST -n 1000 -l SIZESORT- -P 90
```

#### 결과:

- **프리 리스트 소멸**: 프리 리스트에 남아 있는 블록이 거의 없게 됩니다.
- **할당 실패 가능성 증가**: 해제 연산이 거의 없어 메모리가 빨리 소진되고, 새로운 할당 요청이 실패할 가능성이 높아집니다.
- **메모리 고갈**: 할당 가능한 메모리가 빠르게 고갈됩니다.

### 할당 비율이 0에 가까워지면

할당 비율이 0에 가까워지면, 거의 모든 연산이 해제 연산이 됩니다. 이미 할당된 블록이 계속 해제되어 프리 리스트가 커집니다.

예를 들어, 할당 비율을 10%로 설정한 경우:

```
./malloc.py -S 1000 -b 1000 -H 4 -a 4 -p BEST -n 1000 -l SIZESORT- -P 10
```

#### 결과:

- **프리 리스트 증가**: 대부분의 할당 블록이 해제되어 프리 리스트에 추가됩니다.
- **메모리 이용 효율 저하**: 해제 연산이 많아 메모리가 충분히 남아 있지만, 메모리 활용률이 낮습니다.
- **단편화 가능성 감소**: 빈번한 해제로 인해 큰 연속 블록이 유지될 가능성이 높아집니다.

### 결론

- **할당 비율이 50 이상**: 할당 블록이 증가하고 프리 리스트가 줄어듭니다. 할당 비율이 높을수록 메모리 단편화 및 할당 실패 가능성이 증가합니다.
- **할당 비율이 100에 가까움**: 거의 모든 연산이 할당 연산이므로 메모리가 빠르게 고갈됩니다. 할당 실패 가능성이 매우 높습니다.
- **할당 비율이 0에 가까움**: 대부분의 연산이 해제 연산이므로 프리 리스트가 커지고 메모리 단편화가 감소합니다. 큰 블록 할당이 쉬워집니다.

이러한 시나리오들은 메모리 관리 전략을 설계할 때 중요한 고려 사항이 됩니다. 할당과 해제의 균형을 맞추는 것이 메모리 효율성과 성능을 유지하는 데 중요합니다.

## 질문 7. 고도로 단편화된 프리 공간을 생성하려면 어떤 종류의 특정 요청을 만들 수 있나요? -A 플래그를 사용하여 단편화된 프리 리스트를 생성하고, 다양한 정책과 옵션이 프리 리스트의 구성을 어떻게 변경하는지 확인하세요.

고도로 단편화된 프리 공간을 생성하기 위해서는 메모리를 반복적으로 할당하고 해제하여 많은 작은 프리 블록이 생성되도록 할 수 있습니다. 이는 프리 리스트에 여러 크고 작은 블록이 섞이도록 하여 단편화를 유도합니다.

### 고도로 단편화된 프리 공간을 생성하는 방법

다음은 `-A` 플래그를 사용하여 특정 연산 시퀀스를 통해 고도로 단편화된 프리 리스트를 생성하는 예입니다. 그런 다음, 다양한 정책과 옵션이 프리 리스트의 구성을 어떻게 변경하는지 확인합니다.

#### 시뮬레이션 설정

1. 힙 크기: 1000
2. 시작 주소: 1000
3. 헤더 크기: 4
4. 정렬: 4
5. 정책: 최적 적합(BEST-FIT)
6. 프리 리스트 정렬: 크기 내림차순(SIZESORT-)
7. 고도로 단편화된 프리 공간 생성: -A 플래그 사용

### 단편화된 프리 리스트 생성

다음은 고도로 단편화된 프리 리스트를 생성하는 연산 시퀀스 예입니다. 작은 크기의 메모리를 할당하고 해제하여 단편화를 유도합니다:

```
./malloc.py -S 1000 -b 1000 -H 4 -a 4 -p BEST -l SIZESORT- -A +50,-0,+10,-0,+30,-0,+5,-0,+40,-0,+25,-0,+15,-0
```

### 예상 결과

이 명령어는 아래와 같은 방식으로 메모리를 할당 및 해제하여 단편화를 유도합니다:

1. 50바이트 할당
2. 50바이트 해제
3. 10바이트 할당
4. 10바이트 해제
5. 30바이트 할당
6. 30바이트 해제
7. 5바이트 할당
8. 5바이트 해제
9. 40바이트 할당
10. 40바이트 해제
11. 25바이트 할당
12. 25바이트 해제
13. 15바이트 할당
14. 15바이트 해제

이 과정에서 많은 작은 프리 블록이 생성되어 프리 리스트가 고도로 단편화됩니다.

### 프리 리스트 구성 변화 확인

다음으로 다양한 정책과 옵션이 프리 리스트의 구성을 어떻게 변경하는지 확인합니다.

#### BEST-FIT 정책과 크기 내림차순 정렬

```
./malloc.py -S 1000 -b 1000 -H 4 -a 4 -p BEST -l SIZESORT- -A +50,-0,+10,-0,+30,-0,+5,-0,+40,-0,+25,-0,+15,-0
```

예상 결과:

- 할당과 해제가 반복되어 프리 리스트에 여러 크기의 블록이 생성됨.
- BEST-FIT 정책으로 인해 가장 작은 충분한 크기의 프리 블록이 선택됨.
- 프리 리스트는 크기 내림차순으로 정렬됨.

#### WORST-FIT 정책과 크기 내림차순 정렬

```
./malloc.py -S 1000 -b 1000 -H 4 -a 4 -p WORST -l SIZESORT- -A +50,-0,+10,-0,+30,-0,+5,-0,+40,-0,+25,-0,+15,-0
```

예상 결과:

- WORST-FIT 정책으로 인해 가장 큰 프리 블록이 선택됨.
- 단편화가 더 심해질 수 있음.
- 프리 리스트는 크기 내림차순으로 정렬됨.

#### FIRST-FIT 정책과 크기 내림차순 정렬

```
./malloc.py -S 1000 -b 1000 -H 4 -a 4 -p FIRST -l SIZESORT- -A +50,-0,+10,-0,+30,-0,+5,-0,+40,-0,+25,-0,+15,-0
```

예상 결과:

- FIRST-FIT 정책으로 인해 첫 번째 충분한 크기의 프리 블록이 선택됨.
- 단편화가 줄어들 수 있음.
- 프리 리스트는 크기 내림차순으로 정렬됨.

### 병합을 사용한 시나리오

#### BEST-FIT 정책, 크기 내림차순 정렬, 병합 사용

```
./malloc.py -S 1000 -b 1000 -H 4 -a 4 -p BEST -l SIZESORT- -C -A +50,-0,+10,-0,+30,-0,+5,-0,+40,-0,+25,-0,+15,-0
```

예상 결과:

- 해제된 블록이 인접한 프리 블록과 병합됨.
- 프리 리스트가 병합되어 단편화가 줄어듦.
- 프리 리스트는 크기 내림차순으로 정렬됨.

### 결론

- 특정 요청 시퀀스를 통해 고도로 단편화된 프리 리스트를 생성할 수 있습니다.
- 다양한 메모리 할당 정책(BEST-FIT, WORST-FIT, FIRST-FIT)과 프리 리스트 정렬 순서가 단편화와 프리 리스트 구성에 큰 영향을 미칩니다.
- 병합을 사용하면 단편화를 줄이고 프리 리스트를 더 효율적으로 관리할 수 있습니다.

이를 통해 메모리 관리 전략의 중요성과 각 정책이 메모리 할당 및 해제에 미치는 영향을 잘 이해할 수 있습니다.
