JavaScript

자바스크립트 엔진의 주요 구성 요소

Chrysans 2025. 3. 31. 12:02
728x90
반응형

1. Heap (메모리 할당)

  • 객체, 배열, 함수 등의 참조 타입 데이터가 저장되는 메모리 영역입니다.
  • 구조화되지 않은 큰 메모리 공간으로, 동적 메모리 할당이 이루어집니다.
  • 가비지 컬렉터(Garbage Collector)가 이 영역에서 더 이상 참조되지 않는 객체를 찾아 메모리를 해제합니다.

2. Call Stack (호출 스택)

  • 함수 호출을 추적하는 데이터 구조입니다.
  • 코드가 실행될 때 순차적으로 함수 호출을 스택에 쌓고, 함수 실행이 완료되면 스택에서 제거합니다.
  • LIFO(Last In, First Out) 방식으로 작동합니다.

3. 가비지 컬렉터(Garbage Collector)

  • 더 이상 필요하지 않은 메모리를 식별하고 해제하는 자동화된 메모리 관리 시스템입니다.
  • V8 엔진은 주로 'Mark and Sweep' 알고리즘을 사용합니다.

4. 인터프리터(Interpreter)

  • 자바스크립트 코드를 한 줄씩 읽어 실행하는 컴포넌트입니다.
  • V8 엔진에서는 Ignition이라는 인터프리터를 사용합니다.

5. 컴파일러(Compiler)

  • 최신 자바스크립트 엔진들은 JIT(Just-In-Time) 컴파일러를 포함합니다.
  • 자주 실행되는 코드(핫 코드)를 식별하여 최적화된 기계어로 컴파일합니다.
  • V8 엔진에서는, TurboFan이라는 최적화 컴파일러를 사용합니다.

6. 내부 객체와 메서드

  • 내장 객체(Array, Object, String 등)와 그들의 프로토타입을 구현합니다.
  • 내장 함수와 메서드의 네이티브 구현을 포함합니다.

자바스크립트 런타임 환경의 추가 구성 요소

자바스크립트 엔진 자체는 위의 구성 요소를 가지고 있지만, 자바스크립트가 실행되는 전체 환경(브라우저 또는 Node.js)에는 다음과 같은 추가 요소들이 포함됩니다:

1. 이벤트 루프(Event Loop)

  • 콜 스택이 비어있을 때 콜백 큐에서 함수를 콜 스택으로 이동시키는 메커니즘입니다.
  • 비동기 작업의 처리를 조율합니다.

2. 콜백 큐(Callback Queue)

  • Web API에서 완료된 비동기 작업의 콜백 함수가 대기하는 곳입니다.
  • Task Queue(매크로태스크 큐)와 Microtask Queue(마이크로태스크 큐)로 나뉩니다.

3. Web API (브라우저 환경)

  • DOM, AJAX, setTimeout 등 브라우저에서 제공하는 API입니다.
  • 자바스크립트 엔진 외부에서 비동기 작업을 처리합니다.

4. Node API (Node.js 환경)

  • fs, http, crypto 등 Node.js에서 제공하는 API입니다.
  • libuv 라이브러리를 통해 비동기 I/O 작업을 처리합니다.

용어 정리

 

V8 엔진의 힙 구조

힙(Heap)은 자바스크립트 엔진의 핵심 구성 요소로, 객체, 문자열, 배열 등 동적으로 할당되는 데이터가 저장되는 메모리 영역입니다. V8 엔진(Chrome과 Node.js에서 사용)의 힙은 특별한 구조로 설계되어 있습니다.

1. New space (Young generation)

  • 새로 생성된 객체들이 처음 할당되는 공간입니다.
  • 크기가 작고 빠른 가비지 컬렉션(Minor GC)이 자주 발생합니다.
  • Semi-space: New space는 두 개의 semi-space로 나뉘어 있어서, 한 공간이 가득 차면 살아있는 객체만 다른 공간으로 복사하는 방식으로 GC가 동작합니다.
  • 메모리 할당이 매우 빠르며, 대부분의 객체는 수명이 짧다는 가정하에 최적화되어 있습니다.

2. Old space (Old generation)

  • New space에서 일정 시간(보통 두 번의 Minor GC) 동안 살아남은 객체들이 이동하는 공간입니다.
  • 메이저 가비지 컬렉션(Major GC)이 발생하며, 마이너 GC보다 덜 자주 일어납니다.
  • 두 영역으로 구분됩니다:
    • Old Pointer space: 다른 객체를 참조하는(포인터를 가진) 객체들이 저장됩니다.
    • Old Data space: 원시 데이터(문자열, 숫자, 불리언 등)만 포함하는 객체들이 저장됩니다.

3. Large Object space

  • 크기가 큰 객체들이 저장되는 별도의 공간입니다.
  • 이 공간의 객체들은 일반적인 GC 과정에서 복사되지 않습니다(비용이 많이 들기 때문).

4. Code space

  • JIT 컴파일된 코드가 저장되는 공간입니다.
  • 실행 가능한 메모리 영역입니다.

5. Cell space, Property space, Map space

  • V8 엔진의 내부 메타데이터를 저장하는 공간입니다.
  • Cell space: Cell 객체 저장
  • Property space: 객체의 속성 메타데이터 저장
  • Map space: 히든 클래스(객체의 구조를 추적하는 내부 메커니즘) 저장

Mark and Sweep 알고리즘 설명

Mark and Sweep 알고리즘은 자바스크립트의 메모리 관리 방식으로, 두 단계로 작동합니다:

 

1. Mark 단계

  • 시작점(루트)에서 접근 가능한 모든 객체를 찾아 "살아있음"으로 표시합니다.
  • 루트는 전역 객체, 현재 함수의 지역 변수 등입니다.
  • 루트에서 시작해 참조를 따라가며 모든 연결된 객체를 표시합니다.

2. Sweep 단계

  • 메모리 전체를 검사하여 표시되지 않은 객체를 찾습니다.
  • 표시되지 않은 객체는 더 이상 접근할 수 없으므로 메모리에서 제거합니다.

시각적 예시

[루트] → [A] → [B]
         ↓
        [C]

[D] → [E]  (접근 불가능)

 

Mark 후: A, B, C는 표시됨 Sweep 후: D, E는 메모리에서 제거됨

이 방식으로 개발자가 직접 메모리를 해제하지 않아도 V8 엔진이 자동으로 사용하지 않는 메모리를 회수합니다.

 


 

Task Queue (매크로태스크 큐)

매크로태스크 큐는 다음과 같은 비동기 작업들을 처리합니다:

  • setTimeout(), setInterval() 콜백
  • 이벤트 리스너 콜백 (click, keydown 등)
  • AJAX 요청 응답 처리
  • postMessage(), MessageChannel
  • setImmediate() (Node.js 환경)
  • UI 렌더링 작업

Microtask Queue (마이크로태스크 큐)

마이크로태스크 큐는 다음과 같은 작업들을 처리합니다:

  • Promise 콜백 (.then(), .catch(), .finally())
  • queueMicrotask() 콜백
  • MutationObserver 콜백
  • process.nextTick() (Node.js 환경, 이는 마이크로태스크 큐보다 우선순위가 높음)

중요 포인트

  1. 마이크로태스크 우선순위: 마이크로태스크는 매크로태스크보다 항상 먼저 실행됩니다.
  2. 마이크로태스크 완전 실행: 하나의 매크로태스크가 실행되면, 그 이후 큐에 있는 모든 마이크로태스크가 실행됩니다.
  3. 렌더링 시점: 브라우저는 일반적으로 매크로태스크 사이에 렌더링을 수행하지만, 마이크로태스크 사이에는 렌더링하지 않습니다.
매크로태스크(스크립트<script> 최소 실행) -> 마이크로태스크(promise(then,catch)등) 전부 실행 -> 렌더링 -> 매크로태스크1(setTimeout 등) -> 렌더링2 -> 마이크로태스크(promise(then,catch)등) 전부 실행2 -> 렌더링 -> 매크로태스크2

 

최초 매크로태스크는 이벤트루프가 시작되기전 자바스크립트 엔진에 의해서 실행되는 초기 스크립트인데 매크로태스크는 이벤트루프가 시작되야만 호출/실행 되는걸로 알고 있었지만 이벤트 루프 관점에서 보면 이 실행 자체를 "첫 번째 매크로태스크"로 간주할 수 있다.

 

이 과정을 현실 세계로 비유하면:

 

🛫 비행기(자바스크립트 환경)가 이륙하기 전에 승무원(자바스크립트 엔진)이 먼저 기내 방송(초기 스크립트)을 진행한다.

  • 기내 방송(초기 스크립트) 동안 승객들의 요청(동기 코드)은 즉시 처리됩니다.
  • 일부 요청(비동기 코드)은 "비행 중에 처리하겠습니다"라고 메모(태스크 큐에 등록)해둡니다.
  • 중요한 요청(마이크로태스크)은 기내 방송이 끝난 직후 처리합니다.
  • 그 다음 기내 정리(렌더링)를 한 후에야 이륙(다음 매크로태스크 실행)을 시작합니다.

이륙 후에는:

  • 한 명의 승객 요청(매크로태스크)을 처리한 후
  • 모든 중요 메모(마이크로태스크)를 처리하고
  • 기내 정리(렌더링)를 한 다음
  • 다시 다음 승객 요청(다음 매크로태스크)으로 넘어갑니다.

 

 

728x90
반응형