"매 generational + concurrent + parallel + incremental GC — Young (Scavenger) + Old (Mark-Sweep-Compact) + Orinoco pipeline 으로 매 main-thread pause 의 ms 단위로 압축". 매 Google V8 (Chrome/Node.js/Deno/Edge) 의 메모리 관리. 매 Orinoco (2016~) 프로젝트 의 GC 의 90%+ off-main-thread. 매 2026 의 V8 12.x 의 production state.
매 핵심
매 Heap 구조
New Space (Young Generation): 매 1-8MB. 매 short-lived objects. 매 Scavenger (Cheney's copying) 으로 collect.
From-space + To-space (semi-space). 매 alloc 의 from-space pointer bump.
Scavenge: live objects 의 to-space 로 copy → swap. 매 두 번 survive 한 object 는 Old Space 로 promote.
Old Space: 매 long-lived objects. 매 Mark-Sweep-Compact 으로 collect. 매 Major GC.
Large Object Space: 매 ≥256KB objects (large arrays, strings). 매 직접 alloc, no copy.
Code Space: 매 JIT-compiled code (TurboFan, Maglev, Sparkplug).
Read-Only Space: 매 immutable singletons (true, false, null, undefined).
매 Orinoco (modern GC pipeline)
Concurrent Marking: 매 main-thread alongside 의 worker threads 의 mark phase 실행. Tri-color invariant (white/grey/black) + write barrier 로 mutator 와 coexist.
Parallel Sweeping/Compacting: 매 multiple GC threads 의 simultaneously work.
Incremental Marking: 매 marking 의 small chunks 로 split — 매 main thread pause 의 <1ms 로 amortize.
Lazy Sweeping: 매 sweep 의 alloc time 의 on-demand.
매 Hidden Classes + Inline Caches
매 V8 의 dynamic JS object 의 internally fixed-shape "Hidden Class" 로 represent — 매 property access 의 C++ struct field access 만큼 fast.
매 IC (Inline Cache) 가 call site 에서 매 last shape 의 cache → 매 monomorphic 의 fast path.
매 응용
Node.js backend 의 메모리 leak 의 debugging — heap snapshot, retainer chain.
Browser tab memory budget 관리 — Chrome DevTools Memory tab.
Server-side rendering 의 short-lived object 의 polymorphism 회피로 throughput 증가.
💻 패턴
Heap snapshot in Node.js
constv8=require('v8');constfs=require('fs');// Trigger heap snapshot
conststream=v8.getHeapSnapshot();constfile=fs.createWriteStream(`heap-${Date.now()}.heapsnapshot`);stream.pipe(file);// Open in Chrome DevTools → Memory → Load
# 4GB old space
node --max-old-space-size=4096 server.js
# 64MB young space (default ~16MB)
node --max-semi-space-size=64 server.js
Avoid hidden-class transitions (perf pattern)
// Bad — hidden class transitions
constu1={};u1.name='a';u1.age=1;// shape A → B
constu2={};u2.age=1;u2.name='a';// different shape! (order matters)
// Good — same shape every time
functionmakeUser(name,age){return{name,age};// same hidden class
}
Heap profiling (allocation sampling)
constinspector=require('inspector');constsession=newinspector.Session();session.connect();session.post('HeapProfiler.startSampling');// run workload
session.post('HeapProfiler.stopSampling',(err,{profile})=>{fs.writeFileSync('profile.heapprofile',JSON.stringify(profile));});
Detect memory leak (retainer)
// Common leak: closure holding large object
constcache=newMap();functionhandler(req){consthuge=loadHuge();cache.set(req.id,()=>huge.someMethod());// closure pins huge
}// Fix: WeakRef + WeakMap (2026 standard)
constcache2=newWeakMap();functionhandler2(req){cache2.set(req,loadHuge());// GC eligible when req dies
}
매 결정 기준
상황
Action
Node.js OOM (heap limit)
--max-old-space-size 증가 + heap snapshot 분석
매 잦은 short-lived object → Major GC pressure
Young space 증가 (--max-semi-space-size)
매 polymorphic call site (slow)
Object shape 의 stabilize — 매 same constructor + same property order
매 Large array (>256KB)
Large Object Space 로 직접 — 매 copy 의 X
매 long-running process leak
Heap snapshot + retainer chain — 매 closure / event listener / global Map
기본값: Production 의 매 --max-old-space-size=4096 + heap snapshot 의 weekly capture.
언제: 매 Node.js memory leak 분석 (heap snapshot retainer), 매 V8 GC tuning flag 추천, 매 hidden class transition 의 detect 및 fix, 매 GC pause 분석 (--trace-gc).
언제 X: 매 다른 JS engine (JSC/SpiderMonkey/Hermes) — 매 다른 GC architecture.
❌ 안티패턴
잦은 delete: 매 hidden class transition trigger → polymorphic IC. 매 obj.x = undefined 도 같은 문제. 매 missing values 의 null 로 init from start.
Megamorphic call sites: 매 4+ shapes 의 같은 call site 의 hit → IC 의 megamorphic fallback (slow path).
거대 closure: 매 closure 의 enclosing scope 의 모든 var 의 keep alive — 매 small subset 만 capture (let inside).
--max-old-space-size 의 무한 증가: 매 leak 의 mask — 매 root cause 의 fix.
🧪 검증 / 중복
Verified (V8 공식 blog v8.dev — Orinoco/Sparkplug/Maglev 시리즈, Node.js docs).
신뢰도 A.
🕓 Changelog
날짜
변경
2026-05-08
Phase 1
2026-05-10
Manual cleanup — full V8 heap architecture canonical with Orinoco pipeline and 7 patterns