포도가게의 개발일지

[Java Script] V8엔진 빌드과정 본문

[JS,TS,Node]

[Java Script] V8엔진 빌드과정

grape.store 2022. 2. 4. 15:58
반응형

V8 엔진이란?

- Google에서 만든 JavaScript 컴파일러로 C++언어를 기반으로 만들어 졌습니다.
때문에 독립적으로 실행이 가능하며, 다른 웹 브라우저 없이 JavaScript, Node.js 코드를 컴파일 할 수 있습니다.

 

1. V8은 JS파일을 파서(Parser)에게 넘긴다.

 

2. 파서는 js파일을 분석하고 파싱하여 AST로 변환하게 된다.

* AST 컴파일러에서 널리 사용되는 자료 구조인데, 우리가 일반적으로 작성한 소스 코드를 컴퓨터가 알아먹기 쉽게 구조화한다고 생각하면 된다.

function hello (name) {
  return 'Hello,' + name;
}

// 해당 자바스크립트를 파싱하여 AST로 변환하게 되면 아래와 같은 구조로 바뀐다.

{
  type: 'FunctionDeclaration',
  name: 'hello'
  arguments: [
    {
      type: 'Variable',
      name: 'name'
    }
  ]
  // ...
}

3. 변환된 AST를 인터프리터에게 넘기게 되고 인터프리터는 AST -> 바이트 코드로 변환하게 된다.

* 바이트 코드(Bytecode)고급 언어로 작성된 소스 코드를 가상머신이 한결 편하게 이해할 수 있도록 중간 코드로 한번 컴파일 한 것을 의미한다.(JVM에서도 나온다. java에서는 .java -> .class 바이트 코드 파일로 변환한다)

 

4. 이후 바이트 코드를 실행함으로써 소스 코드는 실제로 작동하게 된다.

 

5. 그 중 자주 사용되는 바이트 코드는 TurboFan 컴파일러로 이동하여 최적화를 거치게 된다.

 

V8 엔진 메모리 구조

Heap memory

- V8이 객체나 다이나믹 데이터를 담아두는 영역이다. 여기는 메모리 영역 중에서 가장 큰 부분을 차지하며, 가비지 컬렉션이 발생하는 곳이다. 오직 New Space와 Old Space만 가비지 컬렉팅의 대상이 된다.(JVM이랑 비슷해 보인다)

  • New Space: New Space 또는 Young generation이라 불리는 곳이며, 새로운 객체 또는 단기간 유효한 객체들이 존재하는 곳이다. 이 영역은 상대적으로 작고, 두개의 별도 공간인 Semi Space가 존재한다. 이는 JVM의 S0 S1과 비슷하다고 볼 수 있다. 이 공간은 Scavenger이른바 Minor GC에 의해서 관리된다. 
  • Old Space: Old Space 또는 Old generation이라고 불리는 곳이며, new space에서 minor GC 사이클로부터 살아남은 객체들이 이동하는 곳이다. 이 영역은 Major GC(Mark-Sweep & Mark-Compact)에 의해서 관리된다.
    • Old Pointer Space: 다른 객체를 가르키는 객체가 보관 되는 곳
    • Old Data Space: 단순히 데이터만 가지고 있는 객체 (특정 객체를 가르키지 않음). Strings, boxed numbers, unboxed doubles의 배열이 New Space의 두번의 minor GC Cycle로 부터 살아남는다면 이쪽으로 이동하게 된다.
  • Large object Space: 다른 Space에 있기에 너무 큰 객체들이 여기에 존재하게 된다. 각 객체들은 mmap을 갖게 된다. 큰 객체들은 절대 가비지 콜렉터에 의해 이동하지 않는다.
  • Code space: Just In Time(JIT) 컴파일러가 컴파일된 코드 블록을 보관하는 곳이다. 실행가능한 메모리가 존재할 수 있는 유일한 곳이다. (코드의 양이 커져서 Large Object Space로 가더라도, 여전히 실행 가능하다.)
  • Cell space, property cell space, map space: 이는 각각 Cells PropertyCells Maps를 가지고 있는다. 각각의 공간에는 모두 동일한 크기의 객체가 포함되어 있으며, 어떤 종류의 객체를 가리킬 수 있는지에 대한 제한이 있기 때문에 수집을 단순화 한다.

각각의 공간은 pages의 세트로 구성되어 있다. 여기서 페이지란, 운영체제 mmap에서 할당된 연속적인 메모리 청크를 의미한다. Large Object Space를 제외하고는, 각각 1MB이다.

 

JavaScript 메모리할당 순서를 볼 수 있음

https://speakerdeck.com/deepu105/v8-memory-usage-stack-and-heap?slide=15 

 

V8 Memory usage(Stack & Heap)

 

speakerdeck.com

가비지 컬렉션

- C 언어같은 저수준 언어에서는 메모리 관리를 위해 malloc() 과 free()를 사용한다. 반면, 자바스크립트는 객체가 생성되었을 때 자동으로 메모리를 할당하고 쓸모 없어졌을 때 자동으로 해제한다(가비지 컬렉션). 이러한 자동 메모리 관리는 잠재적 혼란의 원인이기도 한데, 개발자가 메모리 관리에 대해 고민할 필요가 없다는 잘못된 인상을 줄 수 있기 때문이다.

 

- 자바스크립트에서는 객체가 초기화될때 힙 메모리가 할당된다.

 

Mark & sweep 알고리즘

  • 이 알고리즘은 roots라는 object들(전역변수, 현재함수의 지역변수와 매개변수, 스코프 체인에서 쓰이는 변수와 매개변수)의 집합을 가지고 있다. 때문에 주기적으로 roots로 부터 시작하여 root들이 참조하는 오브젝트들을, mark bit를 true로 바꿔줌으로써 더이상 접근할 수 없는 메모리영역을 찾게 된다.
  • 그 이후에 mark bit가 false인 애들을 가용블록으로 바꾸게 되며 true인애들을 다시 false상태로 바꿔준다.
Comments