Files
2nd/10_Wiki/Topics/Old_Space.md
T

13 KiB

category, tags, title, last_updated
category tags title last_updated
Unified
auto-consolidated
technical-documentation
Old Space (구 세대 공간)|Old Space (구 세대 공간
2026-05-02

Old Space (구 세대 공간)

📌 Brief Summary

Old Space(구 세대 공간)는 V8 자바스크립트 엔진의 힙(Heap) 메모리 영역 중, New Space(신규 공간)에서 발생하는 가비지 컬렉션(GC)을 두 번 이상 생존한 객체들이 승격(Promotion)되어 이동하는 공간입니다 [1-3]. 주로 사용자 세션이나 캐시 데이터 등 수명이 길고 지속적인 상태를 유지하는 객체들을 장기간 저장하는 데 사용됩니다 [4, 5]. 이 공간의 메모리 회수는 빈도가 낮지만 리소스 소모가 큰 Major GC(Mark-Sweep 및 Mark-Compact 알고리즘)에 의해 관리됩니다 [1, 3, 5].


Old Space(또는 Old generation)는 V8 엔진의 메모리 힙 구조에서 단기 생존 영역인 New Space에서 여러 차례의 가비지 컬렉션(GC)을 견뎌낸 장기 생존 객체들이 저장되는 공간입니다 [1-3]. 주로 사용자 세션, 캐시 데이터, 영구 상태와 같은 장기 보존 데이터가 이곳에 보관됩니다 [4]. 이 공간은 수백 메가바이트 이상의 데이터를 담을 수 있도록 훨씬 크게 설계되었으며, Mark-Sweep 및 Mark-Compact 알고리즘을 사용하는 Major GC에 의해 덜 빈번하지만 더 많은 리소스를 소모하여 관리됩니다 [4-7].


오래된 공간(Old Space)은 V8 자바스크립트 엔진의 힙(Heap) 메모리에서 새로운 공간(New Space)에 생성된 후 두 번의 마이너 가비지 컬렉션(Minor GC) 주기 동안 살아남은 장기 생존 객체들이 이동(승격)하여 저장되는 메모리 영역입니다 [1-3]. 이 공간은 비교적 크기가 크고 장기 데이터 보존을 위해 설계되었으며, 마크-스윕(Mark-Sweep) 및 마크-컴팩트(Mark-Compact) 알고리즘을 사용하는 메이저 가비지 컬렉션(Major GC)에 의해 관리됩니다 [3-5].

📖 Core Content

  • 공간의 세분화 및 역할: Old Space는 효율적인 가비지 컬렉션을 위해 두 개의 하위 영역으로 나뉩니다. 첫째는 다른 객체를 가리키는 포인터를 포함하는 객체들이 저장되는 Old-pointer-space입니다 [3, 6, 7]. 둘째는 문자열, 박싱된 숫자 등 포인터가 없는 원시 데이터만 포함하는 객체들이 저장되는 Old-data-space입니다 [3, 6, 7]. GC가 Old-data-space를 처리할 때는 내부 포인터 추적 단계를 건너뛸 수 있어 마킹(Marking) 단계에 소요되는 시간을 단축할 수 있습니다 [4].

  • 가비지 컬렉션 (Major GC): 크기가 작고 수집이 빠른 New Space(Minor GC)와 달리, Old Space는 수백 메가바이트의 데이터를 포함할 수 있으므로 마크-스윕(Mark-Sweep)마크-컴팩트(Mark-Compact) 알고리즘을 통해 관리됩니다 [8]. Major GC는 객체의 참조를 따라가며 살아있는 객체(Black)와 죽은 객체(White)를 식별(Mark)하고, 죽은 객체가 차지한 메모리를 회수(Sweep)합니다 [9, 10].

  • 메모리 단편화 및 압축(Compaction): Old Space에서는 죽은 메모리가 페이지에 남기는 "구멍(holes)"으로 인해 메모리 단편화(Fragmentation) 문제가 크게 발생합니다 [11]. 큰 공간에서 객체를 이동시키는 것은 계산 비용이 매우 높고 모든 참조 포인터를 업데이트해야 하므로, V8은 매 주기마다 객체를 압축하지 않고 필요할 때만 단편화된 페이지에서 라이브 객체를 다른 페이지의 빈 공간으로 마이그레이션(Compaction)하는 방식을 사용합니다 [12, 13].

  • 메모리 튜닝 및 누수 탐지: Node.js 애플리케이션에서 대규모 데이터를 처리할 때 --max-old-space-size 커맨드라인 플래그를 사용하면 Old Space의 최대 크기(예: 4096MB)를 명시적으로 늘릴 수 있어 잦은 가비지 컬렉션으로 인한 성능 저하를 방지할 수 있습니다 [14, 15]. 또한 --trace-gc-verbose 로깅 분석 시, Major GC가 발생한 이후에도 "Old space, used" 크기가 지속적으로 증가한다면 강력한 메모리 누수(memory Leak)의 징후로 판단할 수 있습니다 [16].


  • 객체 승격(Promotion) 메커니즘: 객체는 처음에 New Space에 할당된 후, 두 번의 마이너 가비지 컬렉션(Minor GC 또는 Scavenge)에서 살아남으면 Old Space로 승격(promotion)됩니다 [1, 3, 8]. Old Space는 단기 객체를 빈번하게 수집하는 New Space와 달리 장기적인 저장 목적으로 설계되었습니다 [6].
  • 공간의 세분화: Old Space는 가비지 컬렉션 처리를 최적화하기 위해 두 가지 하위 공간으로 분리되어 관리됩니다 [2, 3, 6].
    • Old-pointer-space: 다른 객체들을 가리키는 내부 포인터를 가질 수 있는 대부분의 장기 생존 객체들이 보관됩니다 [2, 3, 9].
    • Old-data-space: 다른 객체에 대한 포인터 없이 순수하게 로우 데이터(문자열, unboxed double 배열 등)만 포함하는 객체들이 저장됩니다 [2, 3, 9]. 이 데이터 공간은 GC의 마킹 단계에서 포인터 추적(tracing)을 건너뛸 수 있어 가비지 컬렉션 소요 시간을 줄여줍니다 [6].
  • Major GC (가비지 컬렉션): Old Space의 메모리 관리는 Mark-Sweep 및 Mark-Compact 알고리즘을 수행하는 Major GC(전체 가비지 컬렉션) 사이클을 통해 이루어집니다 [1, 3, 5]. 일정량의 메모리가 Old Space로 승격되면 Major GC가 트리거되어 사용되지 않는 메모리(Garbage)를 해제하고 라이브 객체들을 압축하여 파편화를 줄입니다 [1, 7, 10].
  • Write Barriers 및 저장 버퍼(Store Buffer): Old Space의 객체가 New Space의 객체를 참조하는 경우, V8 엔진은 이 참조를 추적하기 위해 'Write Barrier' 코드와 'Store Buffer'를 활용합니다 [11-13]. 이는 스캐빈저(Scavenger)가 New Space를 수집할 때 Old Space 전체를 스캔하지 않고도 해당 참조를 파악할 수 있게 해줍니다 [11, 13].
  • 메모리 튜닝 및 누수 감지: --trace-gc-verbose 플래그를 사용하여 로그를 확인할 때, Major GC 이벤트 이후에도 Old space의 사용량이 지속적으로 증가한다면 메모리 누수(memory Leak)가 발생하고 있다는 강력한 지표가 됩니다 [14]. 개발자는 애플리케이션의 메모리 사용량에 맞게 --initial_old_space_size--max-old-space-size 커맨드라인 플래그를 사용하여 Old Space의 크기를 직접 제어할 수 있습니다 [3, 15].

  • 구조와 분류: V8 엔진은 '세대 가설(Generational Hypothesis)'에 기반하여 힙을 조직하며, 오래된 공간은 이 중 '구세대(Old Generation)'에 해당합니다 [3, 6, 7]. 가비지 컬렉션 시 효율적인 메모리 스캔을 위해, 이 공간은 다른 객체를 가리키는 포인터를 포함하는 'Old-pointer-space'와 문자열이나 박싱된 숫자처럼 원시 데이터만 포함하는 'Old-data-space'로 세분화됩니다 [3, 8, 9]. 데이터 공간을 별도로 분리함으로써 가비지 컬렉터는 불필요한 포인터 추적 단계를 건너뛰어 성능을 최적화할 수 있습니다 [9].
  • 객체의 승격(Promotion): 대부분의 객체는 처음에 할당이 빠르고 크기가 작은 새로운 공간(New Space)에 배치됩니다 [3, 8]. 이 영역에서 발생하는 스캐빈지(Scavenge)라는 마이너 가비지 컬렉션을 두 번 겪고도 살아남은 객체는 수명이 긴 객체로 간주되어 오래된 공간으로 복사되는데, 이 과정을 '승격(Promotion)'이라고 합니다 [1, 2, 10].
  • 메이저 가비지 컬렉션(Major GC): 새로운 공간과 달리 오래된 공간은 수백 메가바이트의 방대한 데이터를 포함할 수 있어 물리적으로 메모리를 복사하는 스캐빈지 방식은 비효율적입니다 [4, 5]. 따라서 V8은 마크-스윕(Mark-Sweep) 및 마크-컴팩트(Mark-Compact) 알고리즘을 적용합니다 [4, 5]. 루트(Root) 객체로부터 도달 가능한 객체들을 마킹(Mark)한 뒤, 도달할 수 없는 메모리 영역을 해제(Sweep)하여 여유 리스트(Free list)로 반환합니다 [5, 11, 12]. 단편화(Fragmentation)가 심한 경우에는 객체들을 이동시켜 여유 공간을 압축(Compact)하는 작업도 함께 수행합니다 [5, 13, 14].
  • 쓰기 장벽(Write Barriers)의 활용: 오래된 공간의 객체가 새로운 공간의 객체를 가리키는 경우, V8은 '쓰기 장벽(Write barrier)' 메커니즘을 이용해 해당 포인터의 위치를 스토어 버퍼(Store buffer)에 기록합니다 [15]. 덕분에 마이너 GC를 수행할 때마다 수백 메가바이트에 달하는 오래된 공간 전체를 스캔할 필요 없이, 새로운 객체의 생존 여부를 신속하게 파악할 수 있습니다 [15, 16].
  • 메모리 분석 및 튜닝 시사점: 브라우저나 Node.js의 타임라인을 통해 힙 할당 시점을 분석할 때, 객체들이 계속해서 가비지 컬렉트되지 않고 오래된 공간에 축적되어 베이스라인 메모리가 지속적으로 상승하는 현상(래칫 패턴, Ratchet pattern)이 발생한다면 이는 메모리 누수의 명확한 징후입니다 [17, 18]. 캐시나 사용자 세션 등 영구적인 데이터가 많은 애플리케이션의 경우 --max-old-space-size 플래그를 설정하여 오래된 공간의 최대 허용 크기를 늘려 충돌이나 성능 저하를 방지할 수 있습니다 [19, 20].

⚖️ Trade-offs & Caveats

  • 과거 데이터와의 충돌: 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
  • 정책 변화: Programming & Language 분야의 자동 자산화 수행.

  • 과거 데이터와의 충돌: 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
  • 정책 변화: Programming & Language 분야의 자동 자산화 수행.

  • 과거 데이터와의 충돌: 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
  • 정책 변화: Programming & Language 분야의 자동 자산화 수행.

🔗 Knowledge Connections

  • Related Topics: New Space (신규 공간), Major GC (주요 가비지 컬렉션), Mark-Sweep-Compact, Memory Leak (메모리 누수)
  • Projects/Contexts: V8 JavaScript Engine, Node.js Memory Management
  • Contradictions/Notes: 소스에 따르면 Old Space 내의 객체를 옮기는 압축(Compaction) 작업은 비용이 매우 많이 들기 때문에, Minor GC처럼 모든 라이브 객체를 복사하는 방식(Scavenger)을 쓰지 않고 단편화가 심한 특정 페이지에 대해서만 제한적으로 압축을 수행합니다 [12, 13].

Last updated: 2026-04-19



  • Related Topics: New Space, Major GC, Mark-Sweep-Compact, Write Barrier, Garbage Collection
  • Projects/Contexts: V8 Engine, Node.js Memory Management
  • Contradictions/Notes: 소스에 따르면 V8은 필요할 경우 운영체제에 더 많은 공간을 요청하여 Old Space 크기를 확장할 수 있으나, V8 Memory Cage(보안 샌드박스 및 포인터 압축) 기능이 활성화된 64비트 시스템에서는 물리적 RAM 용량에 관계없이 V8 힙 전체 크기가 최대 4GB의 연속적인 영역으로 엄격히 제한됩니다 [16-18]. 따라서 Old Space 역시 이 4GB 제한의 영향을 받습니다.

Last updated: 2026-04-19



  • Related Topics: 새로운 공간(New Space), 가비지 컬렉션(Garbage Collection), 세대 가설(Generational Hypothesis), 마크-스윕(Mark-Sweep), 마크-컴팩트(Mark-Compact)
  • Projects/Contexts: V8 엔진 힙 아키텍처(V8 Engine Heap Architecture), 할당 타임라인(Allocation Timeline, Node.js 메모리 튜닝
  • Contradictions/Notes: 소스에 내용 상의 모순은 없으며, V8 메모리 관리의 핵심인 세대 가설에 기반하여 새롭게 생성된 단기 생존 객체 공간(New Space)과 명확하게 분리 관리되어 엔진의 전체적인 가비지 컬렉션 효율을 높인다는 점이 일관되게 강조되고 있습니다.

Last updated: 2026-04-19