[크래프톤정글/WIL] 6주차 회고: Explicit Free List와 가상 메모리 Zero Page, 신뢰와 배려 속에서 폭발한 최고의 몰입

코딩이 어려운 사람·2026년 10월 22일

WIL

목록 보기
6/8

소주제

  1. 6주차 학습 개요와 기술 스택: Explicit Free List와 가상 메모리 Zero Page/CoW 최적화
  2. 내가 직면했던 현실과 경험: 가장 많이 배려받았던 한주, 다시 함께하고 싶은 최고의 협업
  3. 핵심 기술 개념과 코드 분석: 명시적 가용 리스트(Explicit List)의 이중 연결 리스트 구조
  4. calloc이 malloc + memset보다 압도적으로 빠른 가상 메모리 Zero Page와 Copy-on-Write(CoW)
  5. 협업과 소통의 성찰: 심리적 안정감이 만들어내는 폭발적인 몰입(Flow)
  6. 실행 가능한 액션 플랜: 배려를 제도화하는 피어 코드 리뷰 문화
  7. 6주차 핵심 엔지니어링 Q&A 3선

1. 6주차 학습 개요와 기술 스택: Explicit Free List와 가상 메모리 Zero Page/CoW 최적화

6주차는 암묵적 가용 리스트(Implicit Free List)의 탐색 시간 병목을 극복하기 위해, 가용 블록들만을 포인터로 연결하여 관리하는 명시적 가용 리스트(Explicit Free List) 및 분리 가용 리스트(Segregated Free List)를 설계하고, 운영체제의 가상 메모리 페이징 및 Copy-on-Write(CoW) 메커니즘을 심층 분석한 주차였습니다.

[명시적 가용 리스트(Explicit Free List) 메모리 연결 구조]

가용 블록 내부 페이로드 영역 재활용:
+----------------+----------------+----------------+--------------------+----------------+
|  4바이트 헤더  | 8바이트 prev_ptr| 8바이트 next_ptr|  남은 가용 공간    |  4바이트 푸터  |
| [크기 | free=0]| (이전 가용블록) | (다음 가용블록) | (새 데이터 적재용) | [크기 | free=0]|
+----------------+----------------+----------------+--------------------+----------------+
        ▲                                 │
        └─────────────────────────────────┘ (할당된 블록은 건너뛰고 순수 가용 블록만 순회!)

2. 내가 직면했던 현실과 경험: 가장 많이 배려받았던 한주, 다시 함께하고 싶은 최고의 협업

"가장 많이 배려받았던 한주, 또 협업을 하고 싶고, 몰입도가 좋았던 한주였습니다."

정글 과정 통틀어 가장 큰 감동과 성장을 경험한 한 주였습니다. 함께한 팀원들은 서로의 기술적 부족함을 지적하거나 질책하는 대신, 사소한 의견도 경청하고 각자의 페이스를 배려해 주었습니다.

이러한 따뜻한 존중과 배려 속에서 '틀려도 괜찮다'는 강력한 심리적 안정감(Psychological Safety)이 형성되었습니다. 실수를 두려워하지 않고 과감하게 복잡한 포인터 최적화 알고리즘을 제안할 수 있었고, 팀원들과의 화이트보드 토론은 매 순간이 지적 유희처럼 느껴졌습니다. 시간 가는 줄 모르고 코드에 완전히 빠져드는 극도의 몰입 상태(Flow)를 경험했고, "좋은 사람들과 함께하는 협업이 엔지니어를 얼마나 비약적으로 성장시키는가"를 온몸으로 깨달았습니다.


3. 핵심 기술 개념과 코드 분석: 명시적 가용 리스트(Explicit List)의 이중 연결 리스트 구조

3.1 가용 블록 페이로드 공간의 제로 코스트(Zero-Cost) 재활용

할당된 블록은 사용자의 실제 데이터를 담아야 하지만, 해제된 가용 블록의 페이로드는 비어 있는 빈 공간입니다. 명시적 가용 리스트는 이 공간에 가용 리스트 조작을 위한 이전(prev) 및 다음(next) 8바이트 포인터를 저장하여 추가적인 메모리 오버헤드 없이 이중 연결 리스트를 구축합니다.

  • 탐색 시간 단축: 전체 힙 블록 NN개를 모두 뒤져야 했던 암묵적 리스트와 달리, 순수 가용 블록 수 MM(M≪NM \ll N)개만 순회하므로 탐색 시간복잡도가 O(M)O(M)으로 급감합니다.
  • LIFO 삽입 vs 주소 정렬 삽입: 최근 해제된 블록을 리스트 맨 앞(Head)에 O(1)O(1)로 삽입하는 LIFO 방식을 채택하여 반환 속도를 극대화했습니다.

4. calloc이 malloc + memset보다 압도적으로 빠른 가상 메모리 Zero Page와 Copy-on-Write(CoW)

실제 리눅스 환경에서 대용량 메모리(예: 1GB)를 0으로 초기화할 때, malloc 호출 후 memset을 돌리는 것보다 calloc을 호출하는 것이 수백 배 빠릅니다.

[calloc의 커널 Zero Page 매핑과 Copy-on-Write(CoW) 지연 할당]

1. calloc(1GB) 호출 시:
   커널은 물리 DRAM 1GB를 할당하지 않음!
   모든 가상 페이지(VPN) ──► 커널 내부의 단 1개의 물리 "Zero Page"(4KB, 읽기 전용)로 매핑!
   -> 물리 메모리 소모 = 4KB, 페이지 할당 시간 = O(1)에 수렴!

2. 응용 프로그램이 특정 주소에 최초로 값을 쓸 때 (Write Fault 발생!):
   CPU MMU가 페이지 폴트 예외 발생 ──► 커널이 새로운 4KB 물리 프레임 즉각 할당 및 복사 (CoW)
  • memset의 비효율: memset은 가상 주소 공간 1GB 전체를 순회하며 실제로 값을 쓰기 때문에, 262,144번의 페이지 폴트와 수 기가바이트의 물리 DRAM 할당을 즉각 강제하여 시스템을 극도로 느리게 만듭니다.
  • 지연 평가(Lazy Allocation): 운영체제 커널은 실제로 쓰기 전까지 물리 메모리 할당을 최대한 미루는 지연 평가 철학을 통해 성능을 극대화함을 확인했습니다.

5. 협업과 소통의 성찰: 심리적 안정감이 만들어내는 폭발적인 몰입(Flow)

최고의 협업은 팀원들의 뛰어난 기술력만으로 완성되지 않습니다. 오히려 서로를 신뢰하고 배려하는 성숙한 인성과 소통 문화가 전제되어야만 기술력도 100% 발휘될 수 있습니다.

내가 배려받아 최고의 몰입을 경험했듯이, 나 또한 미래의 어떤 팀에서든 동료가 실수할 때 나무라지 않고 "충분히 그럴 수 있습니다, 함께 디버깅해 봅시다"라고 말할 수 있는 심리적 안전판이 되어주어야겠다고 굳게 다짐했습니다. 배려받은 사람이 다른 사람을 배려할 줄 아는 진짜 엔지니어가 됩니다.


6. 실행 가능한 액션 플랜: 배려를 제도화하는 피어 코드 리뷰 문화

  1. 상대방 관점의 커뮤니케이션: 내 주장을 먼저 내세우기 전에 상대방의 아이디어를 끝까지 경청하고, "그 접근법의 장점은 무엇인지"를 먼저 인정한 후 대안을 제시하는 대화법 실천하기.
  2. 긍정적 피어 피드백(Praise in Public): 팀원이 우수한 가설을 세우거나 어려운 디버깅을 해결했을 때 아낌없이 공개적으로 칭찬하고 인정하는 문화 만들기.
  3. 지식의 평등한 공유: 내가 새롭게 알게 된 시스템 메커니즘을 팀의 공용 문서에 기록하여 팀원 전체의 지식 수준을 상향 평준화하기.

7. 6주차 핵심 엔지니어링 Q&A 3선

Q1. 명시적 가용 리스트(Explicit Free List)에서 블록의 최소 크기(Minimum Block Size)가 커지는 이유는?

답변: 암묵적 리스트에서는 4바이트 헤더와 4바이트 푸터만 있으면 되므로 최소 블록 크기가 8~16바이트 수준이었습니다. 반면 명시적 리스트는 가용 블록 내부에 이전 블록 포인터(8바이트)와 다음 블록 포인터(8바이트)를 저장해야 하므로, [4바이트 헤더 + 8바이트 prev + 8바이트 next + 4바이트 푸터]를 합쳐 최소 24바이트(8바이트 정렬 시 24~32바이트) 이상의 크기가 강제됩니다. 이로 인해 초소형 객체를 빈번히 할당할 때 내부 단편화가 증가할 수 있습니다.

Q2. 리눅스 가상 메모리에서 Copy-on-Write(CoW) 메커니즘이 fork() 시스템 콜의 성능을 극대화하는 원리는?

답변: 전통적인 fork()는 부모 프로세스의 전체 물리 메모리를 자식 프로세스에게 1:1로 복사하므로 메모리 낭비와 시간 지연이 극심했습니다. CoW를 적용하면 fork() 호출 시 부모의 페이지 테이블만 복사하여 동일한 물리 프레임을 가리키게 하고 쓰기 권한을 차단(Read-only)합니다. 부모나 자식 중 어느 한쪽이 실제로 데이터를 수정하려 할 때만 하드웨어 예외를 가로채 해당 4KB 페이지만 복사하므로, fork() 직후 exec()를 실행하는 대부분의 프로세스 생성 과정에서 메모리 복사 비용을 거의 0으로 단축시킵니다.

Q3. 분리 가용 리스트(Segregated Free List)가 단일 명시적 가용 리스트보다 메모리 활용도와 할당 속도가 모두 뛰어난 이유는?

답변: 분리 가용 리스트는 블록의 크기별(예: 1~32, 33~64, 65~128...)로 여러 개의 독립된 가용 리스트를 배열로 유지합니다. 특정 크기의 메모리 할당 요청이 들어왔을 때 해당 크기 클래스의 가용 리스트로 O(1)O(1) 즉시 점프하여 탐색하므로 탐색 속도가 압도적으로 빠르며, 크기가 비슷한 블록들끼리 인접하게 모여 배치되므로 작은 요청으로 인해 거대한 가용 블록이 무분별하게 쪼개지는 외부 단편화를 근본적으로 억제하기 때문입니다.


크래프톤 정글 6주차 명시적 가용 리스트와 가상 메모리 Zero Page Copy-on-Write 아키텍처 다이어그램

profile
그사세가 아닌 내세상으로 만들기

0개의 댓글