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): 호출 스택의 각 단계를 나타냄.
printSquare()
추가(Push).
printSquare()
안에 있는 multiply()
추가.
multiply()
가 값을 반환 하고 제거(Pop).
- 반환 값을 받아
console.log()
추가.
console.log()
가 실행 되고 제거.
printSquare()
가 실행이 끝나고 제거.
스택 오버플로우
- 호출 스택이 최대 크기가 되면 스택 날리기(Blowing the stack) 발생.
function foo() {
foo();
}
foo();
단일 호출 스택의 문제
- 단일 스레드는 멀티 스레드에서 일어나는 복잡한 문제가 일어나지 않는 장점이 있지만,
- 제한적으로 실행한다는 문제가 있음.
- 만약 브라우저 런타임 환경에서 복잡한 이미지 처리를 한다고 할때,
- 이미지 처리 작업이 스택을 차지하고 있어 후속 작업을 처리할 수 없어짐. (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도 존재.
- 호출 스택(Call Stack)에 추가(push)된 비동기적 작업은 JS엔진이 아닌 Web APIs(C++로 구현)에 다시 추가(push).
- Web APIs는 비동기 작업을 수행하고, 콜백 큐(Callback Queue)로 코드 추가(push).
콜백 큐(Callback Queue)
이벤트 루프(Event Loop)
- 단일 호출 스택을 이용하는 JS엔진과 상호 연동하기 위한 장치.
- 호출 스택과 콜백 큐를 감시함.
- 호출 스택(Call Stack)이 비어있을 때, 콜백 큐에 대기하고 있던 코드를 호출 스택으로 추가(push).
- 호출 스택에 쌓인 코드가 실행 되고 제거(Pop).
출처