[CSAPP 9장 완전 정복] 9.9(Part 9) 블록 병합(Coalescing) 로직과 실제 구현

2025. 4. 26. 13:43·크래프톤 정글/컴퓨터구조(CSAPP)

블록 병합(Coalescing) 로직과 실제 구현

이번 포스트에서는 메모리 단편화를 줄이기 위한 핵심 기술인 블록 병합(Coalescing)을 구체적으로 살펴보겠습니다. 특히, 병합 로직을 실제 코드 수준에서 어떻게 구현하는지도 함께 다뤄봅니다.

 

 

블록 병합이 필요한 이유

free()로 블록을 해제할 때, 주변에 있는 free block들과 즉시 병합하면 외부 단편화를 크게 줄일 수 있는데요. 이를 통해 큰 메모리 요청이 오더라도 무리 없이 처리할 가능성 또한 높아지게 됩니다.

 

 

병합 시 고려해야 할 4가지 경우

이전의 Boundary Tag를 소개했을 때 앞서 한 번 블록 병합 전략에 대해 소개한 적이 있었는데요. 복습하는 겸 다시 한 번 알아보겠습니다.

  • Case 1: 이전/다음 블록이 모두 할당된 경우
    • 병합 없음
  • Case 2: 이전 블록이 할당됐고, 다음 블록이 free인 경우
    • 현재 블록과 다음 블록을 병합
  • Case 3: 이전 블록이 free이고, 다음 블록이 할당된 경우
    • 이전 블록과 현재 블록을 병합
  • Case 4: 이전/다음 블록이 모두 free인 경우
    • 세 블록 모두 병합

병합 시 각 케이스마다 총 free block 크기를 합산하고, Header 및 Footer를 갱신하게 됩니다.

 

 

Boundary Tag를 활용한 빠른 병합

병합은 O(1) 시간에 처리해야 효율적인데요. 이를 위해 다음 정보를 사용합니다.

  • 현재 블록 바로 뒤의 Header로 다음 블록 상태 확인
  • 현재 블록 바로 앞의 Footer로 이전 블록 상태 확인

Boundary Tag 기법 덕분에, 전체 리스트를 탐색할 필요 없이 바로 병합 여부를 판단할 수 있게 됩니다.

 

 

병합 로직 코드 예시

아래 C 코드는 병합 로직을 구현한 예시인데요. Case 별로 처리가 달리지는 것을 볼 수 있습니다.

static void *coalesce(void *bp) {
    size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp)));
    size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
    size_t size = GET_SIZE(HDRP(bp));

    if (prev_alloc && next_alloc) {            // Case 1
        return bp;
    }
    else if (prev_alloc && !next_alloc) {       // Case 2
        size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
        PUT(HDRP(bp), PACK(size, 0));
        PUT(FTRP(bp), PACK(size, 0));
    }
    else if (!prev_alloc && next_alloc) {       // Case 3
        size += GET_SIZE(HDRP(PREV_BLKP(bp)));
        PUT(FTRP(bp), PACK(size, 0));
        PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
        bp = PREV_BLKP(bp);
    }
    else {                                      // Case 4
        size += GET_SIZE(HDRP(PREV_BLKP(bp))) +
                GET_SIZE(FTRP(NEXT_BLKP(bp)));
        PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
        PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));
        bp = PREV_BLKP(bp);
    }

    return bp;
}

각 경우마다 size를 갱신하고, Header/Footer를 업데이트한 뒤, 병합 결과 블록의 시작 주소를 반환하게 됩니다.

 

 

즉시 병합 vs 지연 병합

  • 즉시 병합: free() 호출 시 바로 주변 블록과 병합 (가장 보편적)
  • 지연 병합: 필요할 때 (예: malloc 실패 시 전체 병합) 수행

학습 및 기본 구현에서는 보통 즉시 병합을 사용하게 됩니다.

 

 

마치면서

이번 편에서는 블록 병합(Coalescing) 기법과 그 실제 구현 방법을 살펴봤습니다. Boundary Tag 덕분에 병합을 매우 빠르게 처리할 수 있고, 이는 메모리 단편화 관리에 핵심적인 역할을 합니다.

 

다음 편에서는 할당기 설계 시 고려해야 할 제약과 성능 목표를 정리하면서, 설계 관점에서 동적 메모리 관리 문제를 바라보는 시각을 넓혀보겠습니다. 감사합니다.

저작자표시 비영리 변경금지 (새창열림)

'크래프톤 정글 > 컴퓨터구조(CSAPP)' 카테고리의 다른 글

[CSAPP 9장 완전 정복] 9.9(Part 11) 메모리 활용률(Peak Utilization) 측정과 평가 지표  (0) 2025.04.26
[CSAPP 9장 완전 정복] 9.9(Part 10) 할당기 설계 시 고려해야 할 제약과 목표  (0) 2025.04.26
[CSAPP 9장 완전 정복] 9.9(Part 8) 블록 분할(Splitting) 로직과 최소 블록 크기 관리  (0) 2025.04.26
[CSAPP 9장 완전 정복] 9.9(Part 7) 블록 배치(Placement) 정책의 종류와 장단점  (0) 2025.04.26
[CSAPP 9장 완전 정복] 9.9(Part 6) 메모리 단편화(Fragmentation)와 대응 전략  (0) 2025.04.26
'크래프톤 정글/컴퓨터구조(CSAPP)' 카테고리의 다른 글
  • [CSAPP 9장 완전 정복] 9.9(Part 11) 메모리 활용률(Peak Utilization) 측정과 평가 지표
  • [CSAPP 9장 완전 정복] 9.9(Part 10) 할당기 설계 시 고려해야 할 제약과 목표
  • [CSAPP 9장 완전 정복] 9.9(Part 8) 블록 분할(Splitting) 로직과 최소 블록 크기 관리
  • [CSAPP 9장 완전 정복] 9.9(Part 7) 블록 배치(Placement) 정책의 종류와 장단점
그냥사람_
그냥사람_
IT 관련 포스팅을 합니다. 크래프톤 정글 8기 정경호
  • 그냥사람_
    그냥코딩
    그냥사람_
  • 전체
    오늘
    어제
    • 글 전체보기 N
      • 크래프톤 정글 N
        • 로드 투 정글(입학시험)
        • CS기초(키워드, 개념정리)
        • 컴퓨터구조(CSAPP)
        • Code 정글(C언어)
        • Equipped in 정글(나만무) N
        • 마이 정글(WIL, 에세이) N
      • 자료구조&알고리즘
        • 자료구조
        • 알고리즘
      • 일상
  • 블로그 메뉴

    • 홈
  • 링크

    • Github
  • hELLO· Designed By정상우.v4.10.3
그냥사람_
[CSAPP 9장 완전 정복] 9.9(Part 9) 블록 병합(Coalescing) 로직과 실제 구현
상단으로

티스토리툴바