[JS] JS엔진과 런타임 환경

Chanki Hong·2023년 1월 2일
0

JavaScript

목록 보기
20/30
post-thumbnail

JS 엔진

  • 대표적으로 Google V8 엔진. (Chrome과 Node.js에서 사용)
  • JS엔진은 Memory Heap과 단일 호출 스택(Call Stack)을 이용함. (JS가 싱글 스레드 기반, 콜백 큐인 이유)
  • JS를 동기적으로 작동시킴.

Memory Heap

  • 메모리 할당이 일어나는 곳.

호출 스택(Call Stack)

  • JS엔진의 호출 스택은 하나이며(싱글 쓰레드), 한 번에 한 작업(Task)만 처리 가능.
  • 코드 실행이 쌓이는 곳.
  • 기본적으로 프로그램 상에서 지금 어디에 위치하는지 기록하는 자료구조임.
  • 함수를 실행하면(실행 커서가 함수 안에 존재하면), 해당 함수는 호출 스택의 가장 상단에 추가(Push).
  • 함수가 끝날 때(리턴값을 반환할 때), 해당 함수는 호출 스택에서 제거(Pop) 됨.
  • 호출 스택은 후입선출; LIFO(Last In Fist Out).
function multiply(x, y) {
  return x * y;
}
function printSquare(x) {
  console.log(multiply(x, x));
}
printSquare(5);
  • 엔진이 위의 코드를 실행하는 시점에는 호출 스택이 비어있음.
  • 스택프레임(Stack Frame): 호출 스택의 각 단계를 나타냄.
  1. printSquare() 추가(Push).
  2. printSquare() 안에 있는 multiply() 추가.
  3. multiply() 가 값을 반환 하고 제거(Pop).
  4. 반환 값을 받아 console.log() 추가.
  5. console.log() 가 실행 되고 제거.
  6. printSquare() 가 실행이 끝나고 제거.

스택 오버플로우

  • 호출 스택이 최대 크기가 되면 스택 날리기(Blowing the stack) 발생.
// foo()가 반복 실행하는 재귀 함수.
function foo() {
  foo();
}
foo(); // RangeError: Maximum call stack size exceeded

단일 호출 스택의 문제

  • 단일 스레드는 멀티 스레드에서 일어나는 복잡한 문제가 일어나지 않는 장점이 있지만,
  • 제한적으로 실행한다는 문제가 있음.
  • 만약 브라우저 런타임 환경에서 복잡한 이미지 처리를 한다고 할때,
  • 이미지 처리 작업이 스택을 차지하고 있어 후속 작업을 처리할 수 없어짐. (blocking 발생)
  • 즉, 오랫동안 응답을 멈출 가능성이 있고,
  • 브라우저는 이 상황에서 오류 메세지를 표시함.
  • 단일 호출 스택의 문제를 비동기적 프로그래밍(Asynchronous Programming)으로 해결 가능.

런타임 환경(runtime environment)

  • 프로그래밍 언어가 구동되는 환경.
  • 런타임 환경에 따라 JS엔진을 포함한 다른 API 등이 제공.
  • JS가 브라우저에서 실행된다면 런타임 환경은 브라우저.
  • JS가 Node.js에서 실행된다면 런타임 환경은 Node.js.

브라우저에서 JS

  • JS엔진과 Web APIs(DOM, Ajax, setTimeout 등), Event Loop, Callback Queue가 관여함.
  • Node.js 환경에서는 다른 API가 제공됨. (라이브러리 등)
  • 특히 DOM 이벤트(click 등), http 요청, 콜백(callback)등 비동기적 실행은 동기 함수와 다른 과정으로 처리됨.

Web APIs(Web Application Programming interfaces)

  • DOM, Ajax, setTimeout 등의 비동기적 작업을 실행.
  • 브라우저가 공통적으로 제공하기로 규약한 API들이 많음. (MDN 보기)
  • 보안이슈로 인해 HTTPS에서만 사용가능한 API도 존재.
  1. 호출 스택(Call Stack)에 추가(push)된 비동기적 작업은 JS엔진이 아닌 Web APIs(C++로 구현)에 다시 추가(push).
  2. Web APIs는 비동기 작업을 수행하고, 콜백 큐(Callback Queue)로 코드 추가(push).

콜백 큐(Callback Queue)

  • 비동기적 작업이 실행된 이후 콜백함수가 보관되는 영역.
  • 호출 스택(call stack)과 다르게 선입선출; FIFO(Fist In Fist Out).
  • Task Queue, Microtask Queue, Animation Frames 3가지가 존재.
    • Task Queue: setTimeout, setInterval, setImmediate, I/O, UI 렌더링 등의 콜백 함수 저장.
    • Microtask Queue: ES6도입.Promise, Object.observe 등의 콜백 함수 저장.
    • Animation Frames: requestAnimationFrame 콜백 함수가 저장.
    • 이벤트 루프(Event Loop)에서 콜백 큐를 가져올 때 우선순위는 Microtask Queue > Animation Frames > Task Queue
    console.log('호출 스택');
     setTimeout(() => console.log('Task Queue'), 0);
     Promise.resolve().then(() => console.log('Microtask Queue'));
     /*
     호출 스택
     Microtask Queue
     Task Queue
     */

이벤트 루프(Event Loop)

  • 단일 호출 스택을 이용하는 JS엔진과 상호 연동하기 위한 장치.
  • 호출 스택과 콜백 큐를 감시함.
  1. 호출 스택(Call Stack)이 비어있을 때, 콜백 큐에 대기하고 있던 코드를 호출 스택으로 추가(push).
  2. 호출 스택에 쌓인 코드가 실행 되고 제거(Pop).

출처

0개의 댓글

관련 채용 정보