V8 엔진의 특징에 대해 간략하게 araboza

대호 Dorant·2025년 3월 27일

저번에는 Nodejs의 탄생배경과 철학적 기반에 대해 알아봤죠? 기억..나..시..죠?

앞으로는 Node.js의 내부 구조와 핵심 원리에 대해서 간략하게 알아보려고 합니다.

오늘은 V8 엔진의 특징에 대해 간략하게 알아보겠습니다.

시작하겠습니다!

V8 JavaScript 엔진: Node.js의 심장

💡 V8은 구글에서 개발한 고성능 Javascript 엔진으로 Node.js의 핵심 엔진 역할을 합니다. 
   무려 크롬 브라우저에서 사용되는 엔진이라구요?

특징

1. JIT (Just-In-Time) 컴파일

  • JavaScript 코드를 실행 직전에 기계어로 컴파일하여 실행 속도를 극대화합니다.
  • 인터프리터 언어의 유연성과 컴파일 언어의 성능을 모두 취하는 방식입니다.
💡 여기서 잠깐! 인터프리터 언어? 컴파일 언어? 가 뭐지?

- 인터프리터 언어
  - 소스 코드를 한 줄씩 읽어가며 즉시 실행하는 방식의 프로그래밍 언어이다.
  - 전체 코드를 미리 기계어로 변환하지 않고, 실행 시점에 코드를 해석하고 실행한다.
  - 마치, 동시 통역사가 한 문장씩 실시간으로 번역해주는 것과 같다.
  - 대표적인 인터프리터 언어: JavaScript, Python, Ruby, PHP
  
- 컴파일 언어
  - 소스 코드 전체를 한 번에 기계어나 중간 코드로 변환한 후에 실행하는 프로그래밍 언어이다.
  - 이 과정을 '컴파일'이라고 하며, 이를 수행하는 프로그램을 '컴파일러'라고 한다.
  - 다시 말해, 인간이 이해할 수 있는 프로그래밍 언어를 컴퓨터가 직접 이해할 수 있는 언어로 번역해주는 것과 같다.

2. 가비지 컬렉션

  • 메모리 관리를 자동화하여 개발자가 직접 메모리 할당/해제를 신경쓰지 않도록 합니다.
  • 세대별 가비지 컬렉션(Generational Garbage Collection) 방식을 사용하여 효율적으로 메모리를 관리합니다.

3. 인라인 캐싱

  • 반복적인 속성 접근을 최적화하여 성능을 향상시킵니다.

  • 객체 구조를 캐싱하여 속성 검색 시간을 단축합니다.

  • 예시)

    function getFullName(person) {
      return person.firstName + " " + person.lastName;
    }
    
    // 이 함수를 수백 번 호출한다고 가정해보자
    getFullName({firstName: "홍", lastName: "길동"});
    getFullName({firstName: "김", lastName: "철수"});
    getFullName({firstName: "박", lastName: "영희"});
    • 만약 인라인 캐싱이 없다면?
      • 매 함수 호출마다 person 객체에서 firstName과 lastName 속성의 위치를 처음부터 찾아야 함
      • 이는 수백 번의 중복된 검색 작업을 의미
    • 하지만, 인라인 캐싱을 적용한다면?
      • 첫 번째 호출 시 JavaScript 엔진은 firstName과 lastName 속성이 객체 내에서 어디에 위치하는지 "기억"(캐싱)함
      • 이후 호출에서는 같은 구조의 객체가 들어오면 캐시된 위치 정보를 사용
      • 속성을 처음부터 다시 찾을 필요 없이 바로 접근 가능

4. 히든 클래스

  • 동적 타입 언어인 JavaScript에 정적 타입 언어와 유사한 최적화를 적용합니다.

  • 객체의 구조적 변화를 추적하여 메모리 접근을 최적화합니다.

  • 예시)

    function Person(name, age) {
      this.name = name;
      this.age = age;
    }
    
    let person1 = new Person("홍길동", 30);
    let person2 = new Person("김철수", 25);

    🔥 V8 엔진에서 일어나는 일:

    1. person1 객체가 생성되면 엔진은 "C0"라는 빈 히든 클래스를 생성
    2. name 속성이 추가되면 "C1"이라는 새 히든 클래스 생성 (name의 메모리 오프셋 기록)
    3. age 속성이 추가되면 "C2"라는 새 히든 클래스 생성 (name과 age의 메모리 오프셋 기록)
      4. person1은 최종적으로 C2 히든 클래스 참조
    4. person2가 생성될 때도 동일한 속성 추가 순서를 따르므로 같은 C2 히든 클래스 사용

이번 주에는 스케줄이 너무 바빠 간략하게 준비해봤습니다.
다음 번에는 V8 엔진의 동작원리에 대해 알아보겠습니다.

그럼 이만.

profile
안녕하세요. 멋쟁이 백엔드 개발자입니다😎😎

0개의 댓글