Files
2nd/01_Archive/2026-04-20/동시성 및 점진적 마킹(Concurrent & Incremental Marking).md

4.5 KiB

동시성 및 점진적 마킹(Concurrent & Incremental Marking)

📌 Brief Summary

동시성 및 점진적 마킹은 가비지 컬렉션(GC) 수행 시 애플리케이션의 'Stop-The-World' 일시 정지 시간을 최소화하기 위해 고안된 고도화된 메모리 관리 기법이다 [1-3]. 동시성 마킹(Concurrent Marking)은 메인 스레드가 애플리케이션 코드를 실행하는 동안 백그라운드 도우미 스레드를 활용해 객체의 도달 가능성을 추적하는 방식이다 [4, 5]. 반면 점진적 마킹(Incremental Marking)은 전체 마킹 작업을 짧은 단위(예: 5~10ms)로 쪼개어 메인 스레드의 애플리케이션 실행과 교차로 수행하는 방식이다 [6, 7].

📖 Core Content

  • 점진적 마킹 (Incremental Marking): 무거운 객체 그래프를 한 번에 스캔하는 대신, 작업을 매우 짧은 여러 번의 일시 정지 상태로 나누어 메인 스레드의 애플리케이션 실행과 번갈아 가며 수행한다 [3, 6, 7]. 마킹이 쪼개져 실행되는 동안 객체 그래프가 변경될 수 있으므로, 처리가 끝난 '검은색(Black)' 객체에서 아직 스캔되지 않은 '흰색(White)' 객체로 새로운 참조가 생성되는 것을 감시해야 한다 [8]. V8 엔진은 쓰기 장벽(Write Barrier)을 이용해 이를 감지하고, 해당 검은색 객체를 다시 '회색(Grey)'으로 되돌려 마킹 대기열에 밀어 넣음으로써 객체 누락을 방지한다 [8]. 이 방식은 한 번의 긴 일시 정지를 없애 반응성을 높이지만, 메인 스레드가 수행하는 전체 GC 작업 시간 자체는 약간 늘어날 수 있다 [3].

  • 동시성 마킹 (Concurrent Marking): 메인 스레드가 자바스크립트 등 애플리케이션 코드를 중단 없이 실행하는 동안, 도우미 스레드들이 백그라운드에서 객체를 탐색하고 마킹하는 작업을 전담한다 [5, 7]. 힙의 메모리가 특정 임계값에 도달하면 여러 스레드에 추적할 포인터들이 할당되며, 백그라운드에서 살아있는 객체들을 식별한다 [9]. 애플리케이션과 가비지 컬렉터가 동시에 객체를 읽거나 수정할 수 있기 때문에 데이터 경쟁(Read/Write race)을 방지하기 위한 동기화 오버헤드가 수반되며, 동시 작업 중 생성된 새로운 참조를 추적하기 위해 쓰기 장벽이 사용된다 [4, 5, 9].

  • 상태 추적 기술 (State Tracking): 동시성 및 점진적 마킹 도중 애플리케이션이 힙의 객체를 수정하는 사항을 추적하기 위해 GC는 특별한 메커니즘을 쓴다. V8의 경우 쓰기 장벽(Write Barrier)이 포인터의 생성과 수정을 기록하여 변경 사항을 감지한다 [8, 9]. IBM Eclipse OpenJ9과 같은 JVM 환경에서는 힙을 512바이트 크기의 카드로 나눈 '카드 테이블(Card Table)' 구조를 사용하여 객체가 업데이트될 때마다 해당 카드를 마킹해 둔 뒤, 나중에 다시 추적할 수 있도록 관리한다 [10, 11].

  • 도입을 통한 성능적 이점: 이 두 기법은 모바일 기기나 대규모 데이터 처리 환경에서 500~1000ms에 달하던 극단적인 가비지 컬렉션 일시 정지를 획기적으로 줄이는 데 기여한다 [6, 12]. 특히 사용자의 입력에 응답하거나 애니메이션을 부드럽게 렌더링해야 하는 인터랙티브 환경에서 버벅거림(Jank)과 지연율을 줄이는 핵심 역할을 한다 [3, 6, 13].

🔗 Knowledge Connections


Last updated: 2026-04-19