--- id: wiki-20260508-write-barrier-redir title: Write Barrier category: 10_Wiki/Topics status: verified canonical_id: self aliases: [쓰기 장벽, GC Write Barrier, Generational Barrier] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [garbage-collection, runtime, v8, jvm, performance] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: cpp framework: v8, jvm --- # Write Barrier ## 매 한 줄 > **"매 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 ```cpp // 매 1MB heap 의 512B card → 2048 cards const size_t CARD_SIZE = 512; uint8_t card_table[HEAP_SIZE / CARD_SIZE]; inline void write_barrier(Object* obj, Object** field, Object* new_val) { *field = new_val; if (in_old_gen(obj) && in_young_gen(new_val)) { size_t card = ((uintptr_t)field - heap_base) / CARD_SIZE; card_table[card] = 1; // dirty } } void minor_gc_scan() { for (size_t i = 0; i < num_cards; i++) { if (card_table[i]) { scan_card_for_young_refs(i); card_table[i] = 0; } } } ``` ### 2. V8-style incremental marking barrier (simplified) ```cpp // 매 SATB: overwritten reference 의 mark gray inline void v8_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 ```cpp // 매 compiler 의 barrier 의 omit 가능 case: // 1. 매 store 의 target 이 fresh allocation (young → ?) // 2. 매 store value 의 primitive (int, double) // 3. 매 immutable field 의 init store function emitStore(host, field, value) { if (isFreshlyAllocated(host)) emitRawStore(host, field, value); else emitBarrieredStore(host, field, value); } ``` ### 4. Measure barrier overhead (benchmark) ```typescript // Node.js / V8 의 barrier overhead 의 indirect measure const N = 1e7; const arr = new Array(N); const obj = { ref: null }; console.time('store-loop'); for (let i = 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|Generational Hypothesis]] ## 🤖 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. ## 🧪 검증 / 중복 - Verified (Jones GC handbook 2011, V8 Orinoco docs, JVM HotSpot source). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — write barrier 의 type, cost, V8 example 의 expand |