[TIL - week7] malloc lab 사전 개념 학습

이지섭·2026년 4월 10일

학습 내용

학습
├── 메모리 기본 개념
│   └── 가상메모리, 페이징, 동적 메모리 할당
├── 메모리 관리 원리
│   └── 단편화, 할당 정책(first/next/best fit), implicit/explicit free list
├── 시스템 동작 이해
│   └── demand-zero memory, 시스템콜, DMA
└── 구현 전 설계 정리
        └── allocator 구조와 탐색/배치 전략 연결 이해

가상메모리

  • 가상 메모리는 프로그램이 “연속된 큰 메모리 공간이 있는 것처럼” 보게 해주는 추상화이고, malloc lab에서는 이 덕분에 heap을 하나의 연속된 주소 공간처럼 관리하는 할당기만 구현하면 된다.

즉, 우리가 다루는 것은 실제 메모리가 아니다. 가상 주소 공간을 다룬다. 실제 메모리 주소로 바꾸는 작업은 운영체제가 담당한다.

가상 메모리를 사용함으로써 프로세스는 다음과 같이 메모리 사용을 쉽게 할 수 있다.

  • 프로세스는 메모리가 연속되어 보인다.
  • 다른 프로세스의 메모리와 내 메모리가 별도인 것처럼 보인다.
  • 본인이 받은 포인터만 잘 관리하면 된다.

따라서, malloc은 가상 주소를 다룬다. 할당기로서 의 역할은 OS가 제공한 큰 주소 공간 안에서 블록 단위로 쪼개고, 합치고, 재사용하는 것이다. malloc에서 메모리를 다루는 단위인 블록을 어떻게 관리하는지가 핵심이다.

정리

  • 가상 메모리는 각 프로세스가 자기만의 연속된 메모리 공간을 가진 것처럼 보이게 하는 추상화다.
  • malloc lab에서 우리가 다루는 것은 실제 물리 메모리가 아니라, 그 가상 주소 공간 안의 heap 영역이다.
  • 그래서 lab의 핵심은 OS 내부 동작이 아니라, heap 안에서 블록을 나누고 합치고 재사용하는 allocator를 구현하는 것이다.

페이징

  • 페이징은 가상 메모리를 고정 크기 조각(page)으로 나눠 관리하는 방식이고, malloc lab에서는 이것을 깊게 구현하지는 않지만 “왜 heap이 페이지 단위로 늘어날 수 있는지” 정도를 이해하는 데 필요하다.

운영체제에서는 메모리를 페이지(page)로 나눠 관리한다. 보통 4096 Bytes(= 4KB) 정도이다. 그리고 실제 물리 메모리도 이 단위로 나눠서 관리한다. 운영체제가 페이지를 실제 메모리에 할당할 때에는 연속되지 않게 할당할 수 있다.

Heap의 크기가 늘어나야 한다면 우리가 구현하는 메모리 할당기는 운영체제에게 Page를 1개 더 달라고 요청해야 한다. 이때, 실제 메모리 상에서는 새롭게 받게 된 Page와 원래 가지고 있던 Page가 바로 붙어있지 않을 수 있다. 그러나 우리가 보고 있는 것은 가상 메모리이기 때문에 할당 받은 두 메모리 주소가 마치 서로 붙어있는 것처럼 사용할 수 있다.

우리가 만들 할당기는 이렇게 주어진 커다란 Page 1개를 본인만의 관리 원칙에 의해 쪼개서 사용하면 된다.

정리

  • 페이징은 가상 메모리를 고정 크기 page로 나누고, 이를 물리 메모리의 frame에 연결해 관리하는 방식이다.
  • malloc lab에서는 paging 자체를 구현하지 않고, 그 위에서 heap을 block 단위로 나누어 관리하는 allocator를 구현한다.
  • 따라서 lab에서 중요한 것은 page table이 아니라, heap 확장 후 free block을 어떻게 배치하고 재사용하느냐이다.

동적 메모리 할당

부제: (힙 & sbrk & malloc & free & 데이터 세그먼트)

  • 동적 메모리 할당은 실행 중에 필요한 만큼 heap에서 메모리를 빌려 쓰고(malloc), 다 쓰면 반납(free)하는 것이며, malloc lab은 바로 이 heap 관리자를 직접 만드는 과제다.

동적 할당이 필요한 이유

  • 동적 할당은 실행 전에 크기나 개수를 알 수 없는 데이터를 다루기 위해 필요하다.
  • 또 스택 변수처럼 함수가 끝나면 사라지면 안 되는 데이터를 오래 유지하기 위해서도 필요하다.
  • 그래서 malloc/free는 가변 크기 입력, 연결 리스트·트리 같은 자료구조, 반환 후에도 살아 있어야 하는 데이터에 쓰인다.

프로그램 메모리의 대략적인 구조

  • 코드 영역(text): 실행 코드
  • 데이터 세그먼트(data/bss): 전역변수, static 변수
  • 스택(stack): 함수 호출, 지역변수
  • 힙(heap): 실행 중 동적으로 할당받는 공간

malloc이 직접 다루는 공간이 바로 힙(heap)이다. 전통적으로 Heap은 데이터 세그먼트 영역의 끝에서부터 자라나는 영역으로 설명된다.

malloc lab에서 구현하게 되는 것

  • 요청 크기에 맞는 블록 찾기
  • 필요하면 heap 늘리기
  • 해제된 블록 다시 재사용하기
  • 인접 free block 합치기

malloc : 사용자가 n바이트 메모리를 달라고 요청한다. 이때, 우리가 구현할 할당기는 적절한 block을 골라주는 역할을 한다. 이때, Heap 공간을 block 단위로 나눠서 관리한다. heap 안에 적절한 공간이 존재하지 않으면 heap을 늘리고 적절한 주소를 반환한다.

추가적으로 다음의 작업을 수행한다.(아직 구체적으로는 몰라도 될 듯)

  • 요청 크기를 정렬(alignment)
  • header/footer 포함 크기 계산
  • fit 찾기
  • 필요하면 split
  • payload 주소 반환

free : 사용자가 해당 블록을 더이상 사용하지 않는다고 한 것이다. 할당기는 해당 블록이 사용 가능하다는 것을 표시하고 주변 블록 중에 사용 가능한 블록이 있으면 방금 사용하지 않게 된 블록과 사용 가능한 블록을 합쳐서 하나의 큰 블록을 만든다.(coalescing) 사용 가능한 리스트에 넣거나 재사용 할 수 있는 상태로 만든다.

sbrk : Heap 영역 안에 줄 블록 자체가 없으면 heap 영역의 크기 자체를 늘려야 한다. 이를 위해 sbrk를 사용한다.

  • sbrk는 프로그램의 data segment 끝(정확히는 program break) 을 늘려 heap 공간을 더 확보하는 오래된 방식이다.
  • malloc lab에서는 보통 진짜 sbrk 대신 mem_sbrk() 같은 래퍼를 쓴다.

정리

  • 동적 메모리 할당은 실행 중 필요한 크기만큼 heap에서 메모리를 빌려 쓰고, 다 쓰면 free로 반납해 재사용하는 방식이다.
  • malloc lab에서는 malloc, free, realloc의 동작을 위해 heap 안의 block을 관리하는 allocator를 직접 구현한다.
  • block이 부족하면 sbrk류 호출로 heap을 늘리고, 해제된 block은 다시 재사용하거나 인접 free block과 합쳐서 관리한다.

단편화(Fragmentation)

  • 메모리 단편화는 free 공간은 남아 있는데도, 그 공간이 쓸모 있게 모여 있지 않아서 malloc 요청을 비효율적으로 처리하게 되는 문제다.

1) 외부 단편화 (external fragmentation)

  • free 공간의 총합은 충분한데
  • 여러 조각으로 흩어져 있어서
  • 큰 요청 하나를 처리하지 못하는 상태

예:

  • free block이 16 + 16 + 16 바이트로 흩어져 있음 (쓸 수 있는 각 블록이 16바이트)
  • 총 48바이트 free
  • 그런데 malloc(40)은 못 줄 수 있음
    한 덩어리 40바이트가 없어서

2) 내부 단편화 (internal fragmentation)

  • 블록을 할당하긴 했는데
  • 실제로 필요한 양보다 더 크게 잡혀서
  • 블록 내부에 남는 낭비가 생기는 상태

예:

  • 사용자는 13바이트 요청

  • 정렬 + 헤더/푸터 때문에 24바이트 블록 할당 (아직 몰라도 되는 내용)

  • 실제 payload 관점에서 남는 부분이 생김
    블록 안쪽 낭비

  • 외부 단편화

    • free block이 잘게 쪼개지면 큰 요청을 처리하기 어려워짐
    • 그래서 coalesce가 중요하다
  • 내부 단편화

    • alignment, minimum block size, header/footer 때문에 생김
    • 완전히 없앨 수는 없고 줄이는 게 목표다

정리

  • 메모리 단편화는 free 공간이 남아 있어도 그 공간이 쓸모 있게 배치되지 않아 메모리 활용이 나빠지는 문제다.
  • 외부 단편화는 free block이 여러 조각으로 흩어져 큰 요청을 처리하지 못하는 경우이고, 내부 단편화는 할당된 블록 내부에 낭비가 남는 경우다.
  • malloc lab에서는 split, coalesce, fit 전략이 단편화를 줄이는 핵심 수단이다.

할당 정책(first/next/best fit)

  • 메모리 할당 정책은 여러 free block 중 어떤 블록을 골라 malloc 요청을 배정할지 정하는 규칙이고, malloc lab에서는 성능과 단편화에 직접 영향을 준다.

어떤 크기의 free block을 줄지에 따라 다음의 항목들이 영향을 받는다.

  • 탐색 속도
  • 단편화 정도
  • heap을 얼마나 자주 늘리는지

3가지 정도만 알면 충분하다.

  • first fit
    • 앞에서부터 보다가 처음으로 맞는 블록을 선택
  • next fit
    • 지난번에 찾던 위치부터 이어서 보다가 처음으로 맞는 블록을 선택
  • best fit
    • 맞는 블록들 중에서 가장 작은 적합 블록을 선택

3가지 정책 중 무엇을 선택하는지에 따라

  • 속도(throughput)
  • 메모리 효율(utilization)이 달라진다.

1) First Fit

malloc lab과의 연결

  • 구현이 가장 단순하다.
  • implicit free list에서 자주 먼저 시도하는 방식이다.

중요한 포인트

  • 앞에서부터 순서대로 탐색
  • 처음 맞는 블록을 바로 사용
  • 탐색을 빨리 끝낼 수 있다

장점

  • 구현이 쉽다
  • 평균적으로 빠른 편이다
  • 디버깅하기 쉽다

단점

  • 앞부분에 작은 조각들이 많이 남기 쉬움
  • free list 앞쪽이 너덜너덜해질 수 있음

2) Next Fit

malloc lab과의 연결

  • first fit의 변형
  • 이전 탐색이 끝난 위치를 기억해야 한다.

중요한 포인트

  • 항상 리스트 맨 앞부터 보지 않음
  • 마지막으로 검사한 지점부터 이어서 탐색
  • 보통 rover 포인터 같은 걸 둔다

장점

  • 앞부분만 계속 뒤지는 현상을 줄일 수 있음
  • first fit보다 어떤 경우 탐색 분산이 됨

단점

  • 구현이 first fit보다 약간 더 복잡
  • 성능이 항상 더 좋은 건 아님
  • 단편화가 오히려 더 안 좋아질 수도 있음

자주 하는 오해

  • “next fit은 first fit보다 무조건 좋다”
    • 아니다. 케이스 따라 다르다.

3) Best Fit

malloc lab과의 연결

  • 가능한 블록을 끝까지 보면서가장 딱 맞는 블록을 찾는 방식이다.

중요한 포인트

  • 한 번 찾았다고 끝내지 않고
  • 더 작은 적합 블록이 있는지 계속 봐야 함
  • implicit list에서는 탐색 비용이 커질 수 있음

장점

  • 큰 블록을 아껴 쓸 가능성이 높음
  • 내부 낭비를 줄이는 데 유리할 수 있음

단점

  • 느릴 수 있음
  • 너무 작은 찌꺼기 블록을 많이 남길 수 있음
  • 실제로는 외부 단편화를 항상 줄인다고 장담 못 함

자주 하는 오해

  • “best fit이면 항상 최고다”
    • 아니다. 이름은 best지만 항상 전체 성능이 최고인 건 아님.

block을 고른 뒤에는 여전히 다음을 고려해야 성능이 좋아진다.

  • split 할지
  • minimum block size를 만족하는지
  • alloc bit 갱신
  • 필요하면 coalesce

정리

  • 메모리 할당 정책은 여러 free block 중 어떤 블록을 선택해 요청을 배정할지 정하는 규칙이다.
  • first fit은 처음 맞는 블록을, next fit은 지난 탐색 위치부터 처음 맞는 블록을, best fit은 가장 작은 적합 블록을 선택한다.
  • malloc lab에서는 이 정책이 탐색 속도와 단편화에 영향을 주므로 find_fit() 설계의 핵심이 된다.

Memory Alignment(메모리 정렬), 최소 블록 크기, split

  • alignment는 블록 크기와 payload 주소를 일정 단위로 맞추는 규칙이고,
  • 최소 블록 크기는 “유효한 블록으로 존재할 수 있는 최저 크기”이며,
  • split은 큰 free block을 나눌 때 남는 조각이 최소 블록 크기 이상일 때만 하는 것이다.

큰 그림

1) memory alignment

  • 왜 필요한가?
    • malloc이 돌려주는 주소가 일정한 정렬 단위(보통 8 또는 16 bytes; CPU에서 한 번에 처리할 수 있는 bit 수에 비례)를 만족해야 하기 때문
    • 그래야 블록들이 일정한 규칙으로 배치되고, 다음 블록 주소 계산도 깔끔해짐
  • 핵심은 다음과 같다.
    • 사용자가 13 bytes를 요청해도 실제로는 정렬 단위에 맞춰 올림해서 더 크게 잡음
    • 즉, requested size실제 block size는 다를 수 있음
  • 예시
    • alignment가 16이면13 -> 16으로 올림
      여기에 헤더/풋터까지 고려하면 실제 블록 크기는 더 커질 수 있음

2) 최소 블록 크기

  • 왜 필요한가?
    • 블록은 단순히 payload만 있는 게 아니라, 헤더/풋터 같은 관리 정보가 들어가야 함
    • explicit free list면 free block 안에 prev/next 포인터도 들어가야 함
    • 그래서 너무 작은 블록은 아예 유효한 블록으로 유지할 수 없음
  • 핵심은 다음과 같다.
    • “이 할당기 구조에서 블록 하나가 존재하려면 최소 몇 바이트가 필요한가?”를 정한 것
    • 이 값보다 작은 블록은 만들면 안 됨
  • 예시
    • implicit free list라면 최소 블록 크기가 비교적 작고
    • explicit free list라면 prev/next 포인터를 위한 공간이 필요해서 최소 블록 크기가 더 커짐

3) split

  • 왜 필요한가?
    • 큰 free block을 통째로 주면 낭비가 큼
    • 그래서 필요한 만큼만 떼어 주고, 나머지는 free block으로 남기고 싶음
  • 핵심은 다음과 같다.
    • 남는 조각이 최소 블록 크기 이상이면 split
    • 남는 조각이 너무 작으면 split하지 않고 통째로 할당
  • 예시:
    • free block 64

    • 요청 후 필요한 크기 32

    • 남는 크기 32

    • 최소 블록 크기가 32면 split 가능

      split 할 수 없는 경우의 예시:

    • free block 48

    • 필요한 크기 32

    • 남는 크기 16

    • 최소 블록 크기가 32면 split 불가 → 그냥 48 전체 할당

malloc lab과의 연결

  • malloc lab에서는 malloc(size)가 들어오면 다음과 같은 동작을 한다.
    1. 요청 크기를 alignment에 맞게 조정하고
    2. 그 크기를 담을 수 있는 free block을 찾고
    3. 남는 공간이 최소 블록 크기 이상인지 보고 split 여부를 결정한다.

즉, 이 셋은 한 흐름으로 볼 수 있다.

정리

  • alignment는 malloc이 반환하는 블록 크기와 주소를 일정 단위로 맞추기 위한 규칙이다.
  • 최소 블록 크기는 헤더/풋터와 free list 정보까지 포함해서 블록이 유효하게 존재할 수 있는 최저 크기다.
  • 그래서 malloc lab에서는 큰 free block을 나눌 때 남는 조각이 최소 블록 크기 이상일 때만 split한다.

implicit/explicit free list

  • implicit free list는 heap에 있는 블록들을 전체 순회하며 free block을 찾는 방식이고, explicit free list는 free block들만 따로 연결 리스트로 관리하는 방식이다.

malloc의 핵심은 결국 다음과 같다.

  • 쓸 수 있는 free block을 빨리 찾기
  • free된 블록을 다시 관리하기

이 free block에 대한 관리법이 바로 implicit/explicit free list에 해당한다. 선택에 따라 구현 난이도, 디버깅 난이도가 달라진다.

1) Implicit free list

  • heap 안의 모든 블록이 순서대로 놓여 있다고 본다.
  • 헤더를 읽으면서 다음을 수행하며 한 칸씩 전진한다.
    • 크기 확인
    • 할당 여부 확인
  • free block만 따로 연결하지 않는다.

2) Explicit free list

  • free block만 따로 연결 리스트로 묶어 둔다.
  • 그래서 malloc 때는 할당된 블록은 건너뛰고
    free block들만 탐색한다.

free block에 대한 방법을 선택하는 것은 다음의 항목들에 영향을 준다.

  • find_fit() 성능 차이
  • free() 했을 때
    • implicit: alloc bit만 바꾸고 필요 시 coalesce
    • explicit: 거기에 더해 free list에 삽입/삭제도 해야 함

실제 구현과 관련해서는 다음과 같이 정리된다.

1) Implicit free list

malloc lab과의 연결

  • boundary tag, coalesce, first fit 구조를 익히기 좋다

구현 관점에서 중요한 포인트

  • 헤더의 크기 정보를 이용해서 다음 블록으로 이동
  • 필요하면 footer로 이전 블록 상태 확인
  • find_fit()이 heap 전체를 순회할 수 있음
  • 구조가 단순해서 디버깅이 쉽다

장점

  • 구현이 단순함
  • 블록 구조 이해에 좋음
  • 팀원 설명이 쉬움

단점

  • 느릴 수 있음
  • free block이 적어도 alloc block까지 전부 훑을 수 있음
  • throughput이 불리해질 수 있음

헷갈리기 쉬운 포인트

  • implicit “free list”라고 해서
    free block끼리 진짜 포인터로 연결된 건 아님
  • 그냥 heap 전체를 암묵적 순서로 따라가는 것이다

2) Explicit free list

malloc lab과의 연결

  • 성능을 더 노릴 때 자주 가는 구조이다
  • 특히 implicit보다 탐색량을 줄일 수 있다

구현 관점에서 중요한 포인트

  • free block의 payload 일부를 써서
    • prev
    • next
      포인터를 저장하는 경우가 많다
  • free() 시 free list에 삽입
  • malloc() 시 선택된 free block을 free list에서 제거
  • coalesce() 시 기존 이웃 free block들을 free list에서 빼고, 합쳐진 새 블록을 다시 넣어야 한다

장점

  • free block만 탐색하므로 빠를 가능성이 큼
  • 큰 trace에서 throughput 개선 기대 가능

단점

  • 구현 복잡
  • free list 삽입/삭제 버그가 나기 쉬움
  • coalesce 때 실수하기 쉬움

헷갈리기 쉬운 포인트

  • explicit free list라고 해서heap 순서와 free list 순서가 같은 건 아님
  • free list는 보통:
    • LIFO로 넣을 수도 있고
    • 주소순으로 넣을 수도 있다
  • 즉, 메모리 상 이웃 관계리스트 연결 관계를 구분해야 한다

정리

  • implicit free list는 heap에 있는 모든 블록을 순서대로 훑으며 free block을 찾는 방식이고, explicit free list는 free block들만 따로 연결 리스트로 관리하는 방식이다.
  • implicit는 구현이 단순하고 디버깅이 쉬운 반면, explicit는 free block만 탐색하므로 성능 면에서 유리할 수 있다.
  • malloc lab에서는 보통 implicit로 먼저 구조를 안정화한 뒤, 시간이 되면 explicit free list로 확장해 성능을 개선하는 전략이 현실적이다.

demand-zero memory

중요한 연결 포인트

  • malloc()은 보통 0 초기화를 보장하지 않는다
  • calloc()0 초기화된 메모리를 기대한다
  • OS가 페이지 단위로 demand-zero를 지원하면 큰 새 영역을 0으로 준비하는 비용을 줄일 수 있다

큰 그림

  • OS는 보안상 이전 프로세스가 쓰던 데이터가 새 프로세스에 보이면 안 된다.
  • 그래서 새 메모리를 줄 때는 보통 0으로 초기화된 상태여야 한다.
  • 그런데 매번 큰 메모리를 미리 전부 0으로 채우면 비효율적이다.
  • 그래서 OS는 다음과 같은 선택을 한다.
    • “이 주소 범위는 0인 것처럼 취급하자”
    • 실제로 접근이 일어날 때만 0으로 된 실제 페이지를 붙인다

즉:

필요해질 때(demand) 0 페이지를 준다(zero).

정리

  • demand-zero memory는 새 메모리를 미리 전부 0으로 채우지 않고, 해당 페이지에 처음 접근할 때 0으로 초기화된 페이지를 붙여주는 방식이다.
  • 이것은 allocator가 아니라 OS의 가상 메모리 관리 기법이다.
  • malloc lab에서는 직접 구현하지 않지만, 새 페이지와 재사용 block의 차이, 그리고 malloccalloc의 차이를 이해하는 데 도움이 된다.

시스템콜

  • 시스템콜은 사용자 프로그램이 운영체제에게 “이 작업 좀 대신 해줘”라고 요청하는 공식 창구이고, malloc lab에서는 특히 heap을 늘리는 요청(sbrk 계열) 과 연결된다.

큰 그림

  • 프로그램은 마음대로 하드웨어/메모리 관리 기능을 직접 건드리지 못한다.
  • 대신 시스템콜(system call) 로 운영체제에 요청한다.
  • 예를 들면:
    • 파일 읽기/쓰기
    • 프로세스 생성
    • 메모리 확보
    • 네트워크 사용

즉:

시스템콜은 사용자 프로그램과 OS 사이의 공식 인터페이스다.(소통 창구)

malloc lab에서 직접 쓰이는 부분

  • 실제 세상에서는 allocator가 메모리가 부족할 때sbrk, mmap 같은 OS 인터페이스를 통해 공간을 얻는다.
  • malloc lab에서는 보통 진짜 시스템콜 대신mem_sbrk() 같은 시뮬레이션 함수를 쓴다.
  • 즉, lab에서는:
    • 시스템콜 자체를 구현하는 게 아니라
    • 시스템콜이 해주는 “heap 확장” 효과만 흉내 낸다

malloc lab에서 이해하면 좋은 부분

  • heap이 부족할 때 OS 도움을 받아 더 큰 공간을 얻는다는 개념
  • sbrk가 왜 등장하는지 이해
  • mem_sbrk()가 왜 필요한지 이해
  • malloc은 block 관리자이지, OS 자체가 아니라는 점 구분

자주 하는 오해

  • malloc은 시스템콜이 아니라 보통 라이브러리 함수다.
  • 시스템콜은 allocator가 heap을 늘릴 때 배경에서 필요한 것이다.
  • malloc lab에서는 시스템콜 내부보다 heap 확장 후 block 관리가 더 중요하다.

정리

  • 시스템콜은 사용자 프로그램이 운영체제에게 파일 입출력이나 메모리 확보 같은 작업을 요청하는 공식 인터페이스다.
  • malloc 자체는 시스템콜이 아니라 라이브러리 함수지만, heap이 부족하면 내부적으로 OS의 메모리 관리 기능과 연결될 수 있다.
  • malloc lab에서는 이 과정을 직접 구현하지 않고 mem_sbrk()로 시뮬레이션하며, 핵심은 그로부터 받은 heap 공간을 block 단위로 관리하는 것이다.

mmap

큰 그림

  • mmap은 운영체제에게 새로운 메모리 영역을 매핑해 달라고 요청하는 시스템콜
  • sbrk는 heap의 끝(program break)을 늘려서 메모리를 확보하는 방식
  • 즉, 둘 다 “메모리를 얻는 방법”이지만 방식이 다르다

차이점

  • sbrk
    • heap 끝을 뒤로 늘린다
    • 전통적인 heap 확장 방식
  • mmap
    • heap과 별개로 새로운 매핑 영역을 잡는다
    • 큰 메모리를 따로 받는 데 자주 쓰인다

실제 glibc 같은 allocator는 더 복잡해서

  • 작은 요청은 heap에서 처리하고
  • 큰 요청은 mmap으로 별도 영역을 받아 그 포인터를 돌려줄 수도 있다.

다시 말하면, 사실은 동적 메모리 할당이 늘 heap에서만 일어나는 것은 아니다.

정리

  • 실제 malloc 구현은 작은 요청은 heap에서, 큰 요청은 mmap으로 받은 별도 영역에서 처리할 수 있다.
  • 따라서 동적 할당 메모리가 항상 heap에만 존재하는 것은 아니다.
  • 하지만 malloc lab에서는 복잡성을 줄이기 위해 heap 기반 allocator만 구현한다고 이해하면 충분하다.

DMA

  • DMA는 CPU가 일일이 복사하지 않아도, 장치가 메모리와 직접 데이터를 주고받게 하는 방식이고, malloc lab에서는 직접 구현에 쓰이진 않지만 “메모리는 CPU만 쓰는 게 아니다” 정도로만 알면 충분하다.

큰 그림

  • 보통 데이터를 옮긴다고 하면 다음의 흐름을 떠올리기 쉽다.
    • 디스크/네트워크 장치 → CPU → 메모리
  • 그런데 이걸 CPU가 매번 다 중간에서 복사하면 비효율적이다.
  • 그래서 DMA(Direct Memory Access)
    • 장치가 CPU를 거치지 않고 메모리와 직접 데이터 전송을 하게 해준다.
  • 핵심 감각:
    • CPU는 “복사 작업을 직접 수행”하는 대신
    • 전송을 지시하고, 끝나면 통지받는 역할에 가까워진다.

예시

  • 파일을 읽어올 때
    • CPU가 디스크에서 한 바이트씩 읽어 RAM에 쓰는 게 아니라,
    • 디스크 컨트롤러가 메모리 특정 영역으로 데이터를 써 넣을 수 있다
  • CPU는 시작/완료를 관리한다.

malloc lab과의 연결

malloc lab 구현에 DMA는 거의 직접 안 쓰인다.

그래도 학습 키워드에 들어간 이유를 malloc lab 관점으로 아주 얕게 연결하면 다음과 같다.

1) 메모리는 CPU만 접근하는 공간이 아니다

  • 장치도 DMA를 통해 메모리에 접근할 수 있다.
  • 즉, 메모리 시스템은 생각보다 OS/CPU/장치가 함께 쓰는 자원이다.

2) 하지만 malloc lab의 관심사는 그게 아니다

  • malloc lab은 다음을 구현하는 과제다.
    • heap block 구조
    • free list
    • split / coalesce
    • fit 전략
  • DMA는 이런 allocator 내부 로직과는 거의 무관하다.

3) 정리

  • "DMA란?"
    • 장치가 메모리에 직접 데이터 전송하는 방식
    • CPU 부담을 줄이기 위한 구조

정리

  • DMA는 장치가 CPU를 거치지 않고 메모리와 직접 데이터를 주고받는 방식이다.
  • 이 방식은 CPU의 복사 부담을 줄이고 입출력을 더 효율적으로 만들기 위해 사용된다.
  • 하지만 malloc lab의 핵심은 heap allocator 구현이므로, DMA는 배경지식 수준으로만 알면 충분하다.
profile
이지섭입니다.

0개의 댓글