1.1 JavaScript Engine
자바스크립트란?
JavaScript를 접하다 보면 이런 수식 문장을 종종 접할 수 있습니다.
싱글 스레드 기반으로 동작하는 인터프리터 언어
이벤트 루프를 기반으로 하는 싱글 스레드 Node.js
초창기에는 웹 페이지의 동작을 정의하는 Client-side 언어였으나, Node.js의 등장으로 Server-side 까지도 개발을 할 수 있게 되었습니다.
중요한 키워드는 싱글 스레드 방식으로 돌아가기 때문에 작업(Task)을 수행할 때 Stack, Queue, Heap과 같은 단일 콜 스택을 가집니다.
Rendering Engine vs. JavaScript Engine
Rendering Engine(Layout Engine)은 HTML과 CSS로 작성된 마크업 관련 코드들을 콘텐츠로서 웹 페이지에 렌더링하는 역할입니다.
반면, JavaScript Engine은 JavaScript로 작성한 코드를 해석하고 실행하는 인터프리터입니다.
주로 웹 브라우저에서 이용되었지만 최근 Node.js와 같이 서버 사이드에서는 Chrome V8과 같은 엔진이 이용됩니다.
전세계적으로 가장 많이 사용 중인 V8은 구글이 개발한 JavaScript Engine이며, 크게 다음의 영역으로 구성되어 있습니다.
- Call Stack
- Heap
- Task Queue(Event Queue)
1.2 호출 스택(Call Stack)
호출 스택(Call Stack)이란 함수의 호출을 스택 방식으로 기록하는 자료구조입니다.
JavaScript의 함수가 실행되는 방식을 보통 다음과 같이 부르기도 합니다.
Run to Completion
이는 JavaScript가 단 하나의 호출 스택을 사용하기 때문입니다.
어느 한 함수가 실행되면 이 함수의 실행이 끝날 때까지 다른 작업(Task)를 수행할 수 없습니다.
JavaScript는 요청(Request)이 들어올 때마다 순차적으로 호출 스택에 담아 처리합니다.
조금 자세히 설명하면 메서드가 실행될 때, Call Stack에 새로운 프레임을 만들고 그곳에 push 합니다.
반대로 메서드의 실행이 다 끝나면 해당 프레임은 pop 이 되는 원리입니다.
아래의 그림을 참고하면 이해하는 데 도움이 될 것입니다.
1.2 Heap
보통 구조화되지 않은 더미(dummy) 메모리 영역을 Heap 이라고 합니다.
JavaScript의 경우 동적으로 생성된 객체(인스턴스)들이 이곳에 할당됩니다.
1.3 Queue(Task Queue or Event Queue)
JavaScript의 런타임 환경에서는 처리해야 할 작업(Task)들을 임시로 저장해두는 대기 장소가 있습니다.
이 대기 장소를 Task Queue 또는 Event Queue 라고 합니다.
호출 스택(Call Stack)이 비어있는 상태일 때 먼저 대기열에 들어온 순서대로 수행됩니다.
1.4 Event Loop
이벤트 루프는 JavaScript와 Node.js 사용에 있어 꼭 알고 있어야 하는 개념입니다.
위에 언급한 대로 JavaScript는 싱글 스레드로 불리는데, 메인 스레드인 이벤트 루프가 싱글 스레드이기 때문입니다.
다음 코드의 실행 순서를 예상해보세요.
function run() { console.log('Good'); } console.log('Hello'); setTimeout(run, 3000); console.log('Bye');
그렇다면 다음 코드 실행 순서는 어떻게 될까요?
function run() { console.log('Good'); } console.log('Hello'); setTimeout(run, 0); console.log('Bye');
그림으로 살펴봅시다!