"매 most objects die young — 매 long-lived objects rarely reference young ones". 매 1984 Lieberman & Hewitt 의 observation 이 modern GC (G1, ZGC, Shenandoah, .NET, V8) 의 generational layout 의 foundation 으로 굳어졌다. 매 2026 시점, ZGC sub-millisecond pause 도 매 weak hypothesis 의 가정 위에서 동작한다.
매 핵심
매 두 hypothesis
Weak: 매 newly allocated objects 의 majority 가 young 일 때 die.
Strong: 매 old objects 의 references 의 대부분이 매 다른 old objects 를 가리킨다 (cross-gen 은 rare).
매 generational GC 의 design
Young / Old generation 으로 heap 의 split.
Young 은 매 frequent + cheap (copying / scavenge).
Old 은 매 infrequent + expensive (mark-compact, concurrent).
Write barrier 로 old→young reference 의 track (card table / remembered set).
매 응용
HotSpot G1 / ZGC — region-based, 여전히 generational (ZGC 는 2024 generational 추가).
Go — non-generational concurrent mark-sweep (의도적 trade-off).
💻 패턴
Young allocation (Java HotSpot)
// Eden 에 allocate — TLAB (Thread-Local Allocation Buffer) 의 bump pointerpublicList<String>formatNames(List<User>users){List<String>out=newArrayList<>(users.size());// Edenfor(Useru:users){out.add(u.firstName()+" "+u.lastName());// 매 short-lived String 들}returnout;// caller 가 hold 하지 않으면 매 next minor GC 에서 collect}
Card table write barrier (개념)
// old→young store 시 매 card 를 dirty mark
voidoop_store(oop*field,oopvalue){*field=value;if(in_old_gen(field)&&in_young_gen(value)){card_table[((uintptr_t)field)>>9]=DIRTY;}}// minor GC 시 dirty card 만 scan → 매 old gen 전체 scan 회피
Tenuring threshold tuning
# HotSpot — survivor 에서 N 번 살아남으면 promote
java -XX:MaxTenuringThreshold=8\
-XX:+PrintTenuringDistribution \
-Xlog:gc*=info \
-jar app.jar
ZGC generational (Java 21+)
java -XX:+UseZGC -XX:+ZGenerational -Xmx16g -jar app.jar
# 매 sub-ms pause + generational 의 throughput 회복
.NET allocation pinning
// LOH (Large Object Heap) → 85_000 bytes 이상 즉시 Gen 2 로// 매 short-lived large array 는 ArrayPool 로 회피varbuf=ArrayPool<byte>.Shared.Rent(1<<20);try{Process(buf);}finally{ArrayPool<byte>.Shared.Return(buf);}
V8 generational (Node.js)
// 매 short-lived object → new space (Scavenge, ~수 ms)
functionhandle(req){consttmp={id:req.id,ts:Date.now()};// new space
returnJSON.stringify(tmp);// 매 die young
}
Allocation profiling
# async-profiler — 매 young allocation hotspot 찾기
./profiler.sh -e alloc -d 30 -f alloc.html <pid>
매 결정 기준
상황
Approach
Throughput 우선 batch
Parallel GC (generational copying)
Low-latency service
ZGC generational / Shenandoah
Predictable small heap
G1 (default Java 17+)
Allocation-heavy hot loop
object reuse / pooling 으로 promotion 회피
Large long-lived cache
off-heap (Chronicle, MapDB) 로 old gen pressure 제거
기본값: Java 21+ 의 G1 (default), latency critical 은 ZGC generational.