"매 inter-generational pointer 의 tracking 의 cost". Write barrier 는 매 generational / incremental GC 가 매 old-gen object 의 reference 가 매 young-gen 의 가리킬 때 매 remembered set 의 update 의 small code snippet. 매 V8 / JVM / .NET 의 모든 modern GC 의 essential primitive — 매 minor GC 가 매 entire old-gen 의 scan 의 회피.
매 핵심
매 why
Generational hypothesis: 매 most objects die young → young-gen 만 frequent collect.
Inter-gen pointer 의 problem: 매 minor GC 의 root 로 매 stack + old→young pointer 의 필요.
Naive: scan all old-gen → expensive.
Solution: 매 write 마다 (old.field = young) 매 barrier 의 firing → remembered set 의 add.
매 type
Snapshot-at-the-Beginning (SATB): 매 incremental marking 의 use (G1, ZGC, V8 Orinoco). 매 overwritten old reference 의 record.
Incremental Update: 매 new reference 의 record (CMS).
Card marking: 매 old-gen 의 fixed-size card (e.g., 512B) 의 dirty bit 의 mark — coarse but cheap.
매 cost
매 store 마다 ~3-5 instruction overhead.
매 hot-loop 의 store 의 bottleneck 가능 — 매 elision optimization 의 important.
💻 패턴
1. Card-marking pseudo-implementation
// 매 1MB heap 의 512B card → 2048 cards
constsize_tCARD_SIZE=512;uint8_tcard_table[HEAP_SIZE/CARD_SIZE];inlinevoidwrite_barrier(Object*obj,Object**field,Object*new_val){*field=new_val;if(in_old_gen(obj)&&in_young_gen(new_val)){size_tcard=((uintptr_t)field-heap_base)/CARD_SIZE;card_table[card]=1;// dirty
}}voidminor_gc_scan(){for(size_ti=0;i<num_cards;i++){if(card_table[i]){scan_card_for_young_refs(i);card_table[i]=0;}}}
// 매 SATB: overwritten reference 의 mark gray
inlinevoidv8_write_barrier(HeapObject*host,Object**slot,Object*value){Object*old=*slot;*slot=value;if(incremental_marking_active&&is_white(old)){mark_gray(old);// 매 not-yet-marked 의 reference 의 처리 보장
}// 매 generational: old→young 의 record
if(host->in_old_space()&&value->in_young_space()){remembered_set.insert(slot);}}
3. JIT-emitted barrier elision
// 매 compiler 의 barrier 의 omit 가능 case:
// 1. 매 store 의 target 이 fresh allocation (young → ?)
// 2. 매 store value 의 primitive (int, double)
// 3. 매 immutable field 의 init store
functionemitStore(host,field,value){if(isFreshlyAllocated(host))emitRawStore(host,field,value);elseemitBarrieredStore(host,field,value);}
4. Measure barrier overhead (benchmark)
// Node.js / V8 의 barrier overhead 의 indirect measure
constN=1e7;constarr=newArray(N);constobj={ref: null};console.time('store-loop');for(leti=0;i<N;i++)obj.ref=arr;// 매 barrier 의 fire
console.timeEnd('store-loop');
매 결정 기준
상황
Approach
매 hot inner loop 의 store
primitive 의 use, object reference 의 회피
매 immutable struct
barrier-free design
매 large old-gen
card marking 의 prefer
매 incremental GC
SATB barrier 의 use
매 low-latency (ZGC)
colored pointers + load barrier 의 alternative
기본값: 매 application code 의 barrier 의 invisible — 매 GC 의 implementation detail.
🔗 Graph
부모: Garbage Collection · Memory Management
변형: Card Marking
응용: Incremental GC · Orinoco
Adjacent: Mark Sweep Compact · Garbage Collection
🤖 LLM 활용
언제: GC internals 의 understanding, runtime tuning, performance 의 explain.
언제 X: Rust / non-GC language (no barrier), reference counting (no generational).
❌ 안티패턴
Barrier elision 의 manual attempt 의 application code: 매 unsafe.
Excessive store-to-old-gen 의 hot path: 매 remembered set 의 explosion.
Ignoring barrier cost 의 high-frequency mutation: 매 hidden bottleneck.