본문 바로가기
Dev/javascript

V8! V8! Witeness me! Witness You! Witnessed! - 2

by 괴발짜응 2025. 2. 21.
반응형

블로그를 해 보겠다고 시작한게 2년전이네... ㅋㅋㅋ 온갖 핑계로 아무것도 안하다가 이제 다시 시작한다. 

진짜 야무지게 해야지~

 

이런 자세가 필요하다.


오랜만이야 V8

햇수로 3년전 글에 이은 V8의 작동 방식에 대해 설명한다.

 

V8 엔진은 구글이 개발한 오픈 소스 자바스크립트 엔진으로, 웹 브라우저와 Node.js 등에서 자바스크립트 코드를 빠르고 효율적으로 실행하기 위해 설계 되었다. 그래서 그 동작 방식은 아래와 같다.

 

1. 파싱 및 AST 생성

소스 코드 분석:

자바스크립트 소스 코드를 읽어 들여 먼저 렉서(lexer)에 의해 토큰(token)으로 분해된다.

 

추상 구문 트리 (AST, Abstract Syntax Tree) 생성:

토큰들을 기반으로 파서가 소스 코드의 문법적 구조를 나타내는 트리( AST )를 생성한다.

 

2. 바이트코드 생성 및 Inigtion 인터프리터

바이트코드 생성:

생성된 AST는 V8의 인터프리터인 Inigtion을 위해 바이트코드로 변환된다.

바이트코드는 기계어로 바로 실행되지는 않지만, 인터프리터가 해석하기에 적합한 중간 표현 방식이다.

 

인터프리터: Ignition

Inigtion은 이 바이트코드를 해석하면서 자바스크립트 코드를 즉시 실행한다.

 

빠른 시작:

인터프리터 방식은 컴파일 단계 없이 빠르게 코드를 실행할 수 있도록 도와주며, 초기 실행 속도를 높인다.

 

프로파일링:

실행 중에 코드의 실행 빈도(핫 스팟)를 모니터링하여, 어느 부분이 자주 실행되는지를 기록한다. 이 데이터는 나중에 최적화 컴파일 단계에 사용된다.

 

3. 최적화 컴파일: TurboFan

TurboFan:

Ignition에 의해 실행된 코드 중, 반복적으로 실행되어 성능에 큰 영향을 미치는 "핫"한 부분은 TurboFan이라는 최적화 컴파일러가 대상이 된다.

 

최적화 과정:

TurboFan은 고급 최적화 기법을 사용하여 해당 코드를 기계어로 직접 변환한다. 이를 통해 JIT(Just-In-Time) 컴파일 방식으로 실행 성능을 극대화한다.

 

디옵티마이제이션:

만약 최적화된 코드가 실행 중예상치 못한 동적 변화( ex: 객체 구조가 바뀌거나, 타입이 달라지는 경우)에 부딪히면, TurboFan은 최적화를 최소화하고 다시 인터프리터 모드로 전환하여 안전한 실행을 보장한다. 

 

4. 숨은 클래스와 인라인 캐싱

숨은 클래스 (Hidden Classes):

자바스크립트는 동적으로 객체의 프로퍼티를 추가하거나 수정할 수 있는데, V8은 이러한 동적 객체에 대해 "숨은 클래스"라는 내부 구조를 생성하여, 객체의 형태를 추적하고 최적화한다.

 

인라인 캐싱(Inline Caching):

동일한 프로퍼티 접근이 반복될 경우, 그 결과를 캐시에 저장하여 다음 접근 시 빠르게 처리할 수 있도록 도와준다.

 

5. 가비지 콜렉션 (Garbage Collection)

메모리 관리:

V8은 자동 메모리 관리를 위해 가비지 콜렉션을 수행한다.대부분의 경우 세대별 가비지 컬렉션 방식으로 사용하여, 짧은 생애를 가진 객체와 오래 사는 객체를 구분해 효율적으로 메모리를 회수한다.

 

메모리 최적화:

이를 통해 메모리 누수를 방지하고, 안정적인 장기 실행 환경을 제공한다.

 


V8 엔진은 자바스크립트의 동적 특성에도 불구하고, 다음과 같은 단계와 기법을 통해 고성능 실행을 달성한다.

  1. 파싱 및 AST 생성: 소스 코드를 분석하여 AST를 만들고, 이를 바이트코드로 변환한다.
  2. Ignition 인터프리터: 바이트코드를 빠르게 실행하며, 실행 패턴을 모니터링하여 “핫”한 코드 영역을 감지한다.
  3. TurboFan 최적화 컴파일: 감지된 핫 코드를 프로파일링 데이터를 기반으로 최적화하여 기계어 코드로 변환하고, 실행 속도를 극대화한다.
  4. 숨은 클래스 및 인라인 캐싱: 동적 객체 접근을 최적화하여, 반복되는 프로퍼티 접근의 오버헤드를 줄인다.
  5. 가비지 컬렉션: 세대별 GC를 통해 효율적으로 메모리를 관리하며, 애플리케이션의 안정성을 유지한다.
  6. 디옵티마이제이션: 최적화된 코드가 예상치 못한 동적 변화를 만나면, 안정성을 위해 다시 인터프리터 모드로 전환한다.

이러한 복합적인 전략 덕분에 V8 엔진은 자바스크립트의 유연성을 유지하면서도 놀라운 실행 속도와 효율성을 제공할 수 있다.

 

 

반응형