V8 엔진
Google's open source high-performance JavaScript and WebAssembly engine, written in C++.
— V8 엔진 공식 프로젝트 리포지토리 메인 한 줄 명세
자바스크립트가 다른 언어에 비해 빠르다고 자랑할 수 있는 유일한 이유이자, 구글이 전 세계 개발자들에게 베푼 가장 위대한 공학적 선물. 하지만 V8 엔진이 메모리를 하도 쩝쩝 맛있게 처먹는 바람에 내 컴퓨터의 16GB RAM은 크롬 탭 몇 개 띄우면 숨을 거두게 된다.(...)
1. 개요
구글에서 개발하여 오픈 소스로 배포한 C++ 기반의 초고성능 JavaScript 및 WebAssembly 엔진. 원래 구글 크롬 브라우저의 성능 향상을 목적으로 개발되었으나, 브라우저 환경에 갇혀 있던 자바스크립트를 시스템 영역으로 끌어올린 Node.js의 등장으로 인해 현대 소프트웨어 전반의 아키텍처를 뒤흔든 핵심 심장이 되었다. 인터프리터 방식의 한계를 극한의 JIT(Just-In-Time) 컴파일러 기술로 극복하여, 어설프게 짜여진 자바스크립트 코드조차 엄청난 속도로 실행시키는 기적의 최적화 쇼를 보여준다.
2. 인터프리터를 초월한 JIT 컴파일과 투엔진 시스템
V8 엔진의 압도적인 속도는 JIT(Just-In-Time) 컴파일러 덕분이다. 기존 자바스크립트 엔진들은 코드를 한 줄씩 해석하고 바로 실행하는 인터프리터 방식을 사용해 극도로 느렸으나, V8은 이를 극복하기 위해 다단계 컴파일 아키텍처를 채택했다. 현재 V8 내부에는 Ignition이라는 바이트코드 인터프리터와 TurboFan이라는 최적화 컴파일러가 유기적으로 맞물려 돌아간다. 자주 실행되지 않는 코드는 가볍게 인터프리터로 돌리다가, 자주 실행되는 뜨거운 코드(Hot Code)로 감지되는 순간 TurboFan이 이 코드를 머신 코드로 컴파일 및 최적화하여 네이티브 C++에 준하는 속도로 실행 속도를 폭발시킨다. 물론 동적 타입의 특성 탓에 타입이 도중에 멋대로 바뀌면 최적화가 풀려(Deoptimization) 속도가 지하 바닥으로 처박힌다.1
3. 동적 타이핑의 한계를 극복하는 가상 족보: 히든 클래스
자바스크립트는 실행 중에 객체의 프로퍼티를 마음대로 추가하고 삭제할 수 있는 극단적인 동적 타이핑 언어다. C++이나 Java처럼 메모리 내 프로퍼티의 위치(Offset)를 미리 지정할 수 없어서 탐색 속도가 필연적으로 느릴 수밖에 없는데, V8은 이를 히든 클래스(Hidden Class)라는 혁신적인 개념으로 돌파했다. 객체가 생성되거나 프로퍼티가 추가될 때마다 엔진 내부에서 가상의 고정된 뼈대 레이아웃(히든 클래스)을 생성하고, 프로퍼티 위치를 인덱스화하여 메모리 오프셋을 빠르게 직접 참조하게 만든다. 개발자들에게는 완벽한 자유도를 주면서, 컴파일러 내부에서는 엄격한 정적 타입 언어처럼 동작하게 만드는 기막힌 이중 플레이를 성공시킨 것이다.(...)
4. 관련 밈 및 드립
4.1. 크롬의 램 폭식과 V8의 식성
구글 크롬 브라우저가 메모리를 극단적으로 많이 소모하는 주범으로 V8 엔진이 항상 지목된다. V8은 자바스크립트 코드 실행을 고속화하기 위해 기계어 코드를 메모리에 가득 올려두고, 가비지 컬렉션(GC)을 수행할 때도 성능 병목을 최소화하기 위해 세대별 힙 메모리를 비대하게 잡아 쓰기 때문이다. 네티즌들 사이에서는 '크롬은 내 컴퓨터 RAM을 마시는 괴물이며, V8 엔진 실린더 속에는 옥탄가 대신 메모리가 연소되고 있다'는 짤방 밈이 주기적으로 유행한다.(...)
4.2. 타입을 고수하라는 엔진의 묵언수행
V8의 성능을 100% 끌어쓰기 위해 '자바스크립트 객체의 프로퍼티 구조를 함부로 바꾸지 마라'는 실무 규칙이 있다. 예를 들어 똑같은 구조의 객체 백만 개를 다룰 때 하나의 객체에만 장난으로 임의의 키값을 추가하면 히든 클래스 족보가 꼬여 V8 컴파일러가 삐지게(Deopt) 되며, 성능이 수십 배 감소한다. 이를 두고 개발자들은 '자바스크립트는 겉으로 타입 자유를 외치지만, 실상은 V8의 엄격한 가스라이팅 아래 지배당하고 있다'며 씁쓸해한다.
5. 여담
- 덴마크 농장에서 탄생한 기적: V8 엔진의 개발 총괄자 라스 바크(Lars Bak)는 구글에 합류할 당시, 복잡한 실리콘밸리 사무실 대신 자신의 고향인 덴마크 오르후스의 한 한적한 농장에 개발자들을 모아놓고 농장 헛간에서 V8 엔진을 개발했다. 조용한 자연 속에서 코딩에만 미친 결과물인 셈이다.
- V8의 이름 유래: 고성능 자동차의 상징인 8기통 V형 엔진(V8)에서 이름을 그대로 따왔다. 실제로 엔진 내부의 컴파일러와 인프라 명칭들이 자동차 엔진 튜닝 용어들(TurboFan, Ignition 등)로 가득 차 있어, 개발팀의 지독한 자동차 덕후 감성을 엿볼 수 있다.
- Node.js와의 기막힌 결합: 2009년, 라이언 달(Ryan Dahl)은 V8 엔진이 구글 크롬에 구속되지 않고 독립된 프로세스로 돌아갈 수 있게 감싸고, 여기에 파일 시스템과 네트워크 I/O 라이브러리를 붙여 Node.js를 탄생시켰다. 이로써 백엔드와 프론트엔드가 자바스크립트라는 단일 언어로 통합되는 역사가 시작되었다.
6. 관련 문서
각주
-
예를 들어
function add(a, b) { return a + b; }라는 함수에서a와b가 계속 숫자였다가 갑자기 문자열이 인자로 들어오는 순간, TurboFan은 '사기당했다'며 최적화된 네이티브 코드를 즉시 폐기하고 인터프리터 모드로 백워드하여 느린 원시 연산으로 돌아간다. ↩