Oilpan에서의 포인터 압축
프로그램이 4GB 미만의 RAM을 사용하는 경우 64비트 포인터를 사용하는 것은 절대적으로 터무니없습니다. 그러한 포인터 값이 구조체 안에 나타난다면, 이는 메모리를 절반 이상 낭비할 뿐만 아니라 캐시의 절반을 효과적으로 버리는 셈입니다.
프로그램이 4GB 미만의 RAM을 사용하는 경우 64비트 포인터를 사용하는 것은 절대적으로 터무니없습니다. 그러한 포인터 값이 구조체 안에 나타난다면, 이는 메모리를 절반 이상 낭비할 뿐만 아니라 캐시의 절반을 효과적으로 버리는 셈입니다.
이 글의 제목이 오일팬 관련 책 모음을 깊이 탐구하자는 의미로 보일 수 있으나(오일팬을 위한 구조적 기준을 생각하면 놀라울 정도로 많은 문헌이 이에 대해 다룹니다), 우리는 V8 v9.4부터 라이브러리로 호스팅되고 있는 C++ 가비지 컬렉터인 Oilpan에 대해 좀 더 자세히 살펴보려고 합니다.
2018년 말, 우리는 V8의 메모리 사용량을 대폭 줄이기 위한 V8 Lite라는 프로젝트를 시작했습니다. 처음에 이 프로젝트는 메모리 사용량 감소가 실행 속도보다 중요한 저메모리 모바일 기기나 임베디드 사용 사례에 특화된 Lite 모드라는 독립적인 형태로 구상되었습니다. 하지만 작업을 진행하면서, 이 Lite 모드를 위해 적용된 많은 메모리 최적화 방법이 일반 V8에서도 사용할 수 있어 V8의 모든 사용자에게 이점을 줄 수 있다는 것을 깨달았습니다.
이 게시글은 _동시 마킹_이라는 가비지 컬렉션 기술에 대해 설명합니다. 해당 최적화는 자바스크립트 애플리케이션이 실행을 계속하는 동안 가비지 컬렉터가 힙을 스캔하여 살아있는 객체를 찾고 마킹하도록 허용합니다. 우리의 벤치마크는 동시 마킹이 메인 스레드에서 마킹에 소요되는 시간을 60%–70% 감소시킨다는 것을 보여줍니다. 동시 마킹은 Orinoco 프로젝트의 마지막 퍼즐 조각으로, 기존 가비지 컬렉터를 대부분 동시적이고 병렬적인 새로운 가비지 컬렉터로 점진적으로 대체하는 프로젝트입니다. 동시 마킹은 크롬 64 및 Node.js v10에서 기본적으로 활성화되어 있습니다.
Chrome 66에서 메모리 누수를 디버깅하는 것이 훨씬 쉬워졌습니다. Chrome DevTools는 이제 C++ DOM 객체를 추적하고 스냅샷을 찍을 수 있으며 JavaScript에서 참조된 모든 접근 가능한 DOM 객체를 표시할 수 있습니다. 이 기능은 V8 가비지 컬렉터의 새로운 C++ 추적 메커니즘의 이점 중 하나입니다.
이전 블로그 게시글에서 우리는 가비지 컬렉션이 부드러운 브라우징 경험을 방해하며 발생하는 잉크 문제를 소개했습니다. 이 블로그 게시글에서는 새로운 V8 가비지 컬렉터인 _Orinoco_를 구축하기 위한 세 가지 최적화를 소개합니다. Orinoco는 대부분 병렬적이고 동시적 가비지 컬렉터를 엄격한 세대 경계를 넘어 구현함으로써 가비지 컬렉션 잉크와 메모리 소비를 줄이는 동시에 높은 처리량을 제공할 수 있다는 아이디어를 바탕에 두고 있습니다. Orinoco를 별도의 가비지 컬렉터로서의 플래그 뒤에 구현하는 대신, 즉각적으로 사용자에게 도움을 줄 수 있도록 Orinoco의 기능들을 V8의 최상위 트리에 점진적으로 배포하기로 결정하였습니다. 이번 글에서 논의된 세 가지 기능은 병렬 압축, 병렬 기억 집합 처리, 및 블랙 할당입니다.
JavaScript 성능은 Chrome의 핵심 가치 중 하나로, 특히 부드러운 사용자 경험을 제공하는 데 중요한 요소입니다. Chrome 41부터 V8은 웹 애플리케이션의 반응성을 높이기 위해 고비용의 메모리 관리 작업을 사용되지 않는 작은 유휴 시간 조각 안에서 숨기는 새로운 기술을 활용합니다. 그 결과, 가비지 컬렉션으로 인한 끊김 현상이 크게 줄어들면서 웹 개발자는 더 부드러운 스크롤링과 버터 같은 애니메이션을 기대할 수 있습니다.