Published on

JavaScript의 핵심 원리: 이벤트 루프, 콜 스택, 힙

Authors
  • avatar
    Name
    Inhwan Cho
    Twitter

Javascript의 콜 스택(Call Stack)과 힙(Heap) 이해하기

이 두 용어는 자바스크립트의 실행 컨텍스트와 밀접한 관련이 있으며, 이를 이해한다는 것은 자바스크립트의 동작 원리를 깊이있게 파악하는 것과 같습니다.

콜 스택(Call Stack)

콜 스택은 자바스크립트의 함수 호출을 관리하는 자료구조입니다. 함수를 호출하면 해당 함수는 콜 스택의 최상단에 위치하며, 함수의 실행이 완료되면 스택에서 제거됩니다.

이 과정은 LIFO(Last In, First Out) 원칙을 따릅니다.

예시

index.js
function 첫번째함수() {
  두번째함수();
}

function 두번째함수() {
  console.log('안녕하세요!');
}

첫번째함수();

위 코드에서 첫번째함수를 호출하면 콜 스택에 먼저 쌓이고, 이후 첫번째함수 내부에서 두번째함수를 호출하면 두번째함수가 콜 스택의 최상위에 위치하게 됩니다.

두번째함수의 실행이 완료되면 콜 스택에서 제거되고, 마지막으로 첫번째함수도 스택에서 빠지며 프로그램의 실행이 완료됩니다.


힙(Heap)

힙은 주로 객체와 같은 동적으로 생성된 데이터를 저장하는데 사용되는 메모리 영역입니다.

콜 스택과 달리 힙은 순서에 구애받지 않는 넓은 메모리 영역을 가지고 있으며, 이 곳에서 객체들은 메모리 주소에 의해 접근됩니다.

예시

index.js
let 객체 = {
  이름: '홍길동',
  나이: 30
};

위 코드에서 객체는 힙 영역에 저장됩니다. 이 객체는 동적으로 할당될 공간이 필요하기 때문에 콜 스택이 아닌 힙에 저장되며, 변수 객체는 힙 내의 해당 객체를 가리키는 메모리 주소를 저장합니다.

콜 스택과 힙 비교

구분콜 스택
데이터 구조LIFO (Last In, First Out)순서 없는 넓은 영역
용도함수 호출 관리동적 메모리 할당
저장 데이터기본 데이터 타입 (원시 타입)객체와 같은 참조 타입
접근 속도빠름비교적 느림

위 표와 같이 콜 스택과 힙은 자바스크립트 내에서 서로 다른 역할을 합니다.

콜 스택은 프로그램의 실행 흐름을 관리하는 반면, 힙은 데이터를 저장하는 공간으로 작용합니다.

자바스크립트는 싱글 스레드 기반 언어입니다. 즉, 한 번에 하나의 작업만 처리할 수 있습니다. 그런데 웹 애플리케이션이나 서버 사이드 애플리케이션 같이 많은 작업을 비동기적으로 처리해야 하는 경우가 많습니다. 이때 자바스크립트가 어떻게 효율적으로 작업을 처리하게 되는지, '이벤트 루프(Event Loop)'라는 매커니즘이 중심 역할을 합니다.


이벤트 루프란?

이벤트 루프는 이벤트 루프는 자바스크립트가 비동기 작업을 효율적으로 처리할 수 있게 해주는 핵심 매커니즘입니다.

콜 스택(Call Stack), 이벤트 큐(Event Queue), 백그라운드 태스크를 모니터링하면서,

콜 스택이 비어 있을 때 이벤트 큐에 있는 태스크를 콜 스택으로 옮겨 실행시키는 역할을 합니다.

  • 콜 스택(Call Stack): 코드에서 실행되는 함수들이 순서대로 쌓이는 곳입니다. 함수가 실행되면 스택 최상위에 쌓이고, 작업이 끝나면 스택에서 제거됩니다.
  • 이벤트 큐(Event Queue): 비동기 작업(예: setTimeout, 클릭 이벤트)의 콜백 함수가 실행될 준비가 되면, 이 큐에 쌓이게 됩니다.
  • 백그라운드 태스크: 비동기 처리가 백그라운드에서 실행됩니다. 예를 들어 setTimeout의 콜백 함수는 지정된 시간이 지나면 이벤트 큐로 이동하여 콜 스택이 비어 있는지 확인 후 실행됩니다.

이렇게 이벤트 루프는 자바스크립트가 싱글 스레드임에도 불구하고 효율적인 비동기 처리를 가능하게 합니다.

이벤트 루프 예시

이벤트 루프의 작동 원리를 보다 쉽게 이해하기 위해 간단한 코드 예제를 살펴보겠습니다.

index.js
console.log('첫 번째 메시지');

setTimeout(function() {
    console.log('두 번째 메시지');
}, 0);

console.log('세 번째 메시지');

위 코드를 실행하면 출력 순서는 다음과 같습니다.

  1. 첫 번째 메시지
  2. 세 번째 메시지
  3. 두 번째 메시지

여러분이 생각하실 수 있듯이, setTimeout 함수에 지정된 시간이 0초임에도 두 번째 메시지가 마지막에 출력됩니다.

이는 setTimeout 함수로 인해 해당 콜백 함수가 바로 이벤트 큐에 들어가지만,

콜 스택에 있는 나머지 작업(세 번째 메시지 출력)을 먼저 완료한 후에야 콜 스택으로 이동하여 실행되기 때문입니다.