"한 런타임의 GC를 아는 것과, 모든 메모리 관리가 '언제 회수하고 누가 비용을 치르나'에 다르게 답한 것임을 아는 것은 다르다"
"안 쓰는 메모리를 언제·어떻게 회수하나 — 한 질문, 세 가지 답, 여섯 런타임."
추적 GC(JVM·V8·Go·ART) · 참조 카운팅(Swift ARC) · 소유권(Rust)을 한 자리에 놓고 "무엇이 갈렸는가, 왜 갈렸는가" 를 같은 축으로 비교합니다
메모리 관리 자료는 보통 한 런타임 안에서만 깊어집니다. JVM GC 문서는 G1을 끝까지 파고, Swift ARC 문서는 retain/release만 다룹니다. 그래서 한 언어의 GC를 잘 아는 사람도 "GC와 ARC와 소유권이 같은 문제의 다른 답" 이라는 그림은 잘 그리지 못합니다.
| 일반 자료 | 이 레포 |
|---|---|
| "G1은 영역(Region) 기반 GC다" | JVM G1·ZGC·Go·V8 Orinoco·ART Concurrent Copying을 같은 축(STW·처리량·메모리 헤드룸)에서 비교 |
| "Swift는 ARC를 쓴다" | ARC가 컴파일러가 retain/release를 삽입하는 RC이며, GC와 정반대 트레이드오프(즉시 해제 vs 카운팅 오버헤드 vs 순환 누수)를 가짐을 나란히 본다 |
| "Rust는 GC가 없어서 빠르다" | "런타임 0"의 진짜 의미 — 비용이 컴파일 타임 복잡도와 표현 제약으로 옮겨갔을 뿐 사라지지 않았음 |
| "순환 참조는 메모리 누수다" | 같은 순환 A→B→A가 GC에선 회수되고 ARC/Rc에선 누수되는 이유, 각 모델의 약점 위치가 다른 메커니즘 |
| "GC pause를 줄여야 한다" | 동시 GC의 보편 도구 — 삼색 표시·쓰기 배리어가 JVM·Go·ART에서 같은 알고리즘을 다르게 튜닝한 모습 |
| "Rust는 어렵고 GC는 편하다" | 워크로드(서버·모바일·시스템)가 어떻게 모델 선택을 강제했는지, 정치가 아닌 공학적 논리 |
| 런타임 한 개만 설명 | 동일 데이터 구조를 6런타임으로 측정 — 같은 누수, 다른 약점 |
선행 학습 권장: 각 런타임의 GC/메모리 모델 레포 6개. 이 레포는 그것들을 횡단으로 묶는 수렴점입니다. 아래 🔗 레포 연결 참고.
각 챕터의 첫 문서부터 바로 학습을 시작하세요!
| 항목 | 수치 |
|---|---|
| 챕터 | 7 |
| 문서 | 36 |
| 총 분량 | ~80,000 단어 / ~650 KB |
| 평균 분량 | 문서당 ~2,200 단어 |
| 비교 대상 런타임 | 6 — JVM · V8 · Go · ART · Swift · Rust |
| 모델 | 3 — 추적 GC · 참조 카운팅(ARC) · 소유권 |
💡 각 섹션을 클릭하면 상세 문서 목록이 펼쳐집니다
핵심 질문: 안 쓰는 메모리를 어떻게 안전하게 회수하나 — 그리고 그 비용은 누가 치르나?
두 가지 질문, 수동 관리의 함정, 메모리 계층, 세 접근의 개요, 비교 프레임까지 (5개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 두 가지 질문 | ① 언제 회수가 안전한가(도달 불가)와 ② 누가 비용을 치르나(프로그래머·런타임·컴파일러) — 모든 메모리 전략을 이 두 질문으로 환원하는 프레임 |
| 02. 수동 관리의 문제 | C/C++의 use-after-free·이중해제·누수 사례, 왜 자동화가 필요한가, 그러나 자동화의 비용은 어디로 가는가 |
| 03. 메모리 계층의 그림자 | 회수 비용이 캐시·대역폭·NUMA와 얽히는 지점, 모든 GC 비용의 바닥(computer-architecture-deep-dive 연결) |
| 04. 세 가지 접근의 개요 | 추적 GC·참조 카운팅·소유권이 각자 어디서·언제·어떻게 회수하는지를 한 그림으로, 본 레포의 전체 지도 |
| 05. 비교 프레임 | 평가 축 5개(지연·처리량·메모리 오버헤드·결정성·복잡도)를 정의, 모든 챕터에서 같은 축으로 모델을 평가 |
핵심 질문: 루트에서 도달할 수 없는 객체를 찾아 회수한다는 발상은 어떻게 알고리즘이 되는가?
추적 원리, 표시-쓸기·복사·압축, 세대 가설, JVM·V8·Go GC까지 (6개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 도달 가능성 | 루트 집합에서 시작해 참조 그래프를 순회, 도달 가능한 객체만 살리고 나머지를 회수하는 추적 GC의 공리 |
| 02. 표시-쓸기·복사·압축 | 세 기본 알고리즘의 트레이드오프, 단편화 문제가 압축을 강제하는 이유, 각 알고리즘의 비용 위치 |
| 03. 세대 가설 | "대부분 객체는 일찍 죽는다"는 경험적 가설, young/old 분리가 가져온 처리량 혁명, JVM·V8·ART의 공통 토대 |
| 04. JVM GC — G1과 ZGC | 영역(Region) 기반 G1의 점진적 압축, 컬러 포인터 기반 ZGC의 sub-ms STW 목표 (jvm-deep-dive 연결) |
| 05. V8 Orinoco | Scavenge(young) + Mark-Compact(old), 병렬·동시·증분의 3계층 (v8-engine-deep-dive 연결) |
| 06. Go GC | 세대 없는 동시 삼색 표시, 짧은 STW 목표(<1ms)와 그 대가(높은 메모리 헤드룸) (go-deep-dive 연결) |
핵심 질문: "잠시 멈춤" 없이 살아있는 객체와 죽은 객체를 어떻게 정확히 구분하는가?
STW의 비용, 삼색 표시, 쓰기 배리어, ART, 동시 GC 비교까지 (5개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. STW 문제 | Stop-The-World가 지연·jank·tail latency를 만드는 이유, 서버 SLO와 모바일 60fps에서 STW가 왜 1순위 문제인가 |
| 02. 삼색 표시 | white/grey/black 분류, 동시 표시가 정확성을 유지하기 위한 불변식, 모든 동시 GC의 공통 언어 |
| 03. 쓰기 배리어 | 동시 표시 중 *변이(mutation)*가 일어날 때 정확성을 지키는 컴파일러 삽입 코드, SATB와 incremental update의 두 흐름 |
| 04. ART GC | Concurrent Copying으로 모바일 jank를 0에 가깝게 — Android의 60fps 제약이 어떻게 GC 설계를 결정했는가 (android-runtime-deep-dive 연결) |
| 05. 동시 GC 비교 | JVM ZGC · Go GC · ART CC의 STW 목표 vs 처리량 vs 메모리 오버헤드를 같은 표에 — 같은 알고리즘, 다른 튜닝 |
핵심 질문: "참조 수가 0이 되면 즉시 해제"라는 단순한 규칙은 왜 GC와 정반대 비용 구조를 만드는가?
RC 원리, ARC의 컴파일러 삽입, GC와의 정면 비교, 순환 약점, 비용 측정까지 (5개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 참조 카운팅 원리 | 참조 수를 세어 0이면 즉시 회수하는 결정적 모델, GC 스레드도 STW도 없는 대신 분산된 카운팅 비용 |
| 02. ARC — 컴파일러가 삽입하는 RC | Swift 컴파일러가 retain/release를 결정론적으로 삽입하는 메커니즘 (swift-deep-dive 연결), Objective-C MRC와의 비교 |
| 03. GC vs ARC | 결정성·즉시 회수 vs 카운팅 오버헤드·순환 약점을 같은 축에서 — Bacon의 "A Unified Theory of Garbage Collection"이 말하는 쌍대성 |
| 04. 순환 참조의 약점 | A→B→A가 RC에서 근본적으로 회수 불가인 이유, weak/unowned의 진짜 의미와 수동 해결의 비용 |
| 05. ARC의 진짜 비용 | retain/release 원자적 연산의 빈도와 캐시 영향, 컴파일러 최적화(__owned, retain elision)가 줄여주는 부분과 그렇지 못한 부분 |
핵심 질문: 런타임 메모리 관리 비용을 0으로 만든다는 약속의 대가는 무엇인가?
소유권 모델, RAII, 빌림 검사, Rc/Arc 선택지, 소유권의 비용까지 (5개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 소유권 모델 | 컴파일 타임에 수명 결정 — GC도 RC도 없이 안전을 보장하는 발상의 진짜 의미 (rust-deep-dive 연결) |
| 02. RAII와 drop | 스코프 종료 시 결정적 해제, C++의 RAII를 언어 수준 보증으로 끌어올린 Rust의 변형 |
| 03. 빌림 검사 | UAF·이중해제·data race를 컴파일 타임에 제거하는 메커니즘, 표현 제약과의 트레이드오프 |
| 04. Rc와 Arc — 선택적 RC | Rust도 필요시 참조 카운팅을 옵트인으로 제공, ARC와 달리 모든 객체가 아니라 선택한 객체만 RC |
| 05. 소유권의 비용 | 런타임 0의 대가 — 학습 난이도·표현 제약·컴파일 시간, "fighting the borrow checker" 현상의 정체 |
핵심 질문: 같은 누수 시나리오가 각 모델에서 어떻게 다르게 발현하는가?
순환 참조, 메모리 누수, 지연·처리량·오버헤드·결정성, 6런타임 측정까지 (6개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 순환 참조 | GC: 도달 불가면 회수 (강점) · ARC: 카운트 0 안 됨 (누수) · Rust Rc: 동일 문제, Weak 필요 — 같은 그래프, 세 운명 |
| 02. 메모리 누수의 형태들 | GC의 논리적 누수(살아있는 참조), ARC의 순환 누수, Rust의 Rc 순환과 leak() — 누수의 위치가 다르다 |
| 03. 지연 vs 처리량 | GC의 집중된 STW · ARC의 분산 카운팅 비용 · Rust의 예측 가능한 drop — tail latency가 만들어지는 방식의 차이 |
| 04. 메모리 오버헤드 | GC의 여유 힙(헤드룸) · ARC의 카운트 필드 · Rust의 (거의)0 — 같은 데이터 구조의 실측 메모리 |
| 05. 결정성 | "언제 해제되는가"의 예측 가능성 — GC의 비결정성(finalizer 위험), ARC/Rust의 결정성, finalizer vs Drop의 의미론 차이 |
| 06. 같은 프로그램, 6런타임 측정 | 동일 객체 그래프(트리·DAG·순환)를 6런타임으로 구현, 메모리 피크·해제 지연·STW를 한 표에 정리 |
핵심 질문: 왜 서버는 GC, 모바일은 ARC, 시스템은 소유권으로 갈렸는가 — 그리고 이게 우연인가?
평가 축 종합, 워크로드의 강제, 선택의 논리, 메모리 관리 지형도까지 (4개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 평가 축 종합 | Chapter 1에서 정의한 5축으로 6런타임을 한 표로 — 처음으로 모든 모델이 동일 단위로 비교됨 |
| 02. 왜 갈렸나 — 워크로드의 강제 | 서버(처리량 최우선) → GC, 모바일(저지연·메모리 제약) → ARC/저지연 GC, 시스템(예측성·런타임 0) → 소유권 — 정치가 아닌 공학적 강제 |
| 03. 선택의 논리 | 새 프로젝트의 메모리 전략을 결정하는 의사결정 트리, 워크로드 → 제약 → 모델의 흐름을 체크리스트로 |
| 04. 종합 — 메모리 관리 지형도 | 모든 챕터의 결론을 한 장의 지형도로, 새 런타임(예: 비RC ARC 변형, hybrid GC+RC)을 만나도 이 프레임으로 분류 가능 |
🟢 "GC와 ARC와 Rust가 같은 문제의 다른 답"이라는 핵심만 빠르게 (1주)
핵심 4문서 — 한 질문, 세 답, 한 지형도
Ch1-04 세 가지 접근의 개요
Ch4-03 GC vs ARC (Bacon의 쌍대성)
Ch6-01 순환 참조 — 같은 문제, 세 운명
Ch7-04 메모리 관리 지형도
🔵 메모리 관리의 횡단 그림을 끝까지 (7주)
Week 1 Chapter 1 전체 — 근본 문제와 비교 프레임
Week 2 Chapter 2 전체 — 추적 GC (JVM·V8·Go)
Week 3 Chapter 3 전체 — 동시 GC (삼색·쓰기 배리어·ART)
Week 4 Chapter 4 전체 — Swift ARC와 RC 모델
Week 5 Chapter 5 전체 — Rust 소유권
Week 6 Chapter 6 전체 — 같은 문제, 다른 약점 + 6런타임 측정
Week 7 Chapter 7 전체 — 트레이드오프 종합과 선택 논리
🔴 런타임 선택 의사결정자(아키텍트·CTO) 집중 코스
의사결정에 필요한 최소 경로
Step 1 Ch1-01, 05 두 질문 + 5축 프레임
Step 2 Ch4-03 GC vs ARC 정면 비교
Step 3 Ch5-01, 05 소유권 모델과 그 비용
Step 4 Ch6-03, 04 지연·처리량·메모리 오버헤드 실측
Step 5 Ch7-02, 03 왜 갈렸나 + 선택 논리
각 문서의 "📊 측정" 섹션에서 6런타임 정량 비교를 확인하세요.
모든 문서는 동일한 구조로 작성됩니다. 비교가 핵심이므로 🔬·📊에서 항상 여러 모델을 나란히 다룹니다.
| 섹션 | 설명 |
|---|---|
| 🎯 핵심 질문 | 이 문서를 읽고 나면 답할 수 있는 질문 |
| 🔍 왜 이게 존재하는가 | 풀려는 문제와 설계 배경 — 항상 공통 문제에서 출발 |
| 😱 흔한 오해 또는 잘못된 사용 | Before — "한 모델만 알고 다른 모델을 오해"하는 패턴 |
| ✨ 올바른 이해와 사용 | After — 모델들을 나란히 놓고 본 후의 정확한 그림 |
| 🔬 내부 동작 원리 | 알고리즘·자료구조 + 여러 런타임의 변형 비교 (예: 삼색 표시를 JVM·Go·ART가 어떻게 다르게 구현하나) |
| 💻 실전 실험 | 같은 객체 그래프를 2개 이상 런타임으로 구현, 차이를 눈으로 |
| 📊 측정 | 메모리 피크·STW·해제 지연·throughput을 같은 표로 — 가능한 한 6런타임 모두 |
| 🤔 트레이드오프 | 이 모델의 장단점, 다른 모델이 더 나은 시나리오 |
| 📌 핵심 정리 | 한 화면 요약 |
| 🤔 생각해볼 문제 | 횡단 사고를 강제하는 질문 + 해설 |
polyglot. 같은 객체 그래프를 6런타임으로 측정하는 것이 이 레포의 정체성입니다.
FROM ubuntu:24.04
# JVM (HotSpot 21)
RUN apt-get update && apt-get install -y openjdk-21-jdk
# Go
RUN apt-get install -y golang-go
# Node (V8)
RUN apt-get install -y nodejs npm
# Rust
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
# Swift — 별도 이미지 권장 (swift:6)
# Android/ART — 별도 SDK (android-runtime-deep-dive 참고)# 핵심 검증 1 — 같은 메모리 패턴을 6런타임으로 비교
# 패턴 예: "10만 개 객체 할당 → 절반 unreachable → 회수 관찰"
# 추적 GC 관찰
java -Xlog:gc*,gc+heap=debug demo.java # JVM GC 로그·STW·세대별 회수
GODEBUG=gctrace=1 ./go-demo # Go GC·STW·heap 추적
node --trace-gc --trace-gc-verbose demo.js # V8 GC
# 핵심 검증 2 — ARC 트래픽 관찰 (Swift)
swiftc -emit-sil demo.swift | grep -E 'retain|release' # 컴파일러 삽입 카운팅
# Xcode Instruments — Allocations · Leaks · ARC traffic
# 핵심 검증 3 — Rust (런타임 0)
cargo build # drop 시점이 컴파일 타임 결정
# 누수 가능 경로: Rc<RefCell> 순환만 (Weak 미사용 시) 또는 명시적 Box::leak
# 핵심 검증 4 — 순환 참조의 운명 비교
# JVM/Go/JS: A→B→A 순환이어도 GC가 회수 (도달 불가면) ✓
# Swift ARC: 강한 순환 → 누수, weak/unowned 필요 ✗
# Rust Rc: Rc 순환 → 누수, Weak 필요 ✗
# → GC의 강점이 RC/소유권의 약점, 정확히 같은 입력에 다른 결과
# 측정 — 동일 객체 그래프의:
# 메모리 피크 (RSS, heap)
# 해제 지연 (객체 도달 불가 → 메모리 해제까지)
# STW 분포 (p50, p99, max)
# 할당/해제 throughput
# 를 6런타임에서 같은 단위로 비교⬆️ 선행 (이 비교의 입력 — 각 런타임의 메모리 모델을 깊게)
jvm-deep-dive → JVM GC (G1·ZGC) 내부
v8-engine-deep-dive → V8 Orinoco (Scavenge + Mark-Compact)
go-deep-dive → Go GC (동시 삼색, 세대 없음)
android-runtime-deep-dive → ART Concurrent Copying
swift-deep-dive → Swift ARC (컴파일러 삽입 RC)
rust-deep-dive → Rust 소유권·빌림 검사
🤝 시너지 (메모리 관리의 *바닥*과 *수단*)
computer-architecture-deep-dive → 메모리 계층·캐시·NUMA (모든 GC 비용의 바닥)
compiler-deep-dive → 컴파일러가 retain/release·drop·write barrier를 삽입
🧬 본질
이 레포 = 6개 런타임의 메모리 전략이 수렴하는 지점
한 런타임 깊이 → 횡단 비교 → 새 런타임을 만나도 이 프레임으로 분류
- The Garbage Collection Handbook — Jones, Hosking, Moss (모든 GC 알고리즘의 결정판)
- "A Unified Theory of Garbage Collection" — Bacon, Cheng, Rajan (GC와 RC가 쌍대임을 증명)
- JVM HotSpot GC 문서
- V8 Orinoco — Trash talk: the Orinoco garbage collector
- Go GC Guide
- ART GC — Source.android.com
- Swift Automatic Reference Counting
- The Rust Programming Language — Ownership
- 각 선행 레포(jvm·v8·go·android-runtime·swift·rust)의 참고자료 — 이 레포는 그 종합입니다.