[TECH-QA] ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋Ÿฐํƒ€์ž„

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ๋กœ ๋™์ž‘ํ•˜์ง€๋งŒ, ๋น„๋™๊ธฐ ์ž‘์—…์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ž˜ ๊ตฌ์„ฑ ์š”์†Œ๋“ค์ด ์ƒํ˜ธ์ž‘์šฉํ•ฉ๋‹ˆ๋‹ค.

๊ด€๋ จ ํ‚ค์›Œ๋“œ

Call Stack

Heap

Web API

Task Queue (Macro Task Queue)

Microtask Queue

Event Loop

  • Call Stack : ์‹คํ–‰ ์ค‘์ธ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ๊ด€๋ฆฌ.
  • Heap : ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์„ ๊ด€๋ฆฌ.
  • Web API: : ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌ(๋ธŒ๋ผ์šฐ์ € ์ œ๊ณต).
  • Task Queue (Macro Task Queue) : ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์ฝœ๋ฐฑ ๋Œ€๊ธฐ์—ด.
  • Microtask Queue : ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ๋น„๋™๊ธฐ ์ž‘์—… ๋Œ€๊ธฐ์—ด..
  • Event Loop : ์Šคํƒ๊ณผ ํ ์‚ฌ์ด์˜ ์ž‘์—… ์ด๋™์„ ์กฐ์ •.

Call Stack (ํ˜ธ์ถœ ์Šคํƒ)

์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ์ด๋ฏ€๋กœ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์ž‘์—…๋งŒ ์ˆœ์„œ๋Œ€๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. Heap์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•˜๋ฉฐ ๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๋น„๋™๊ธฐ ์ž‘์—…์€ Web API๋กœ ๋„˜๊ธฐ๊ณ , ์Šคํƒ์€ ๋ฐ”๋กœ ๋‹ค์Œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
function a() { b(); }
a์™€ b๊ฐ€ ์Šคํƒ์— ์ˆœ์ฐจ์ ์œผ๋กœ ์Œ“์˜€๋‹ค๊ฐ€ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

Heap (ํž™)

์ฃผ๋กœ ๋™์ ์œผ๋กœ ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ(์˜ˆ: ๊ฐ์ฒด, ๋ฐฐ์—ด, ํ•จ์ˆ˜ ๋“ฑ)๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์กฐํ™”๋˜์ง€ ์•Š์€ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์œผ๋กœ, ๋ณ€์ˆ˜๋‚˜ ํ•จ์ˆ˜์˜ ์‹ค์ œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜(Garbage Collection)์ด ์ฃผ๊ธฐ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.Call Stack์—์„œ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ, ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜๋‚˜ ๊ฐ์ฒด๋Š” Heap์— ์ €์žฅ๋˜๊ณ , ์Šคํƒ์€ ๊ทธ ์ฐธ์กฐ๋งŒ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
let obj = { name: "myName" };
์œ„ ์ฝ”๋“œ์—์„œ obj๋Š” ์Šคํƒ์— ์ฐธ์กฐ๋กœ ์ €์žฅ๋˜๊ณ , { name: "myName" }๋Š” Heap์— ์ €์žฅ๋˜๋ฉฐ ๋น„๋™๊ธฐ ์ž‘์—…์—์„œ ์ƒ์„ฑ๋œ ๊ฐ์ฒด(์˜ˆ: Promise ๊ฐ์ฒด)๋„ Heap์— ์ €์žฅ๋˜๋ฉฐ, ์ดํ›„ Microtask Queue๋‚˜ Task Queue์—์„œ ์ฐธ์กฐ๋ฉ๋‹ˆ๋‹ค.

Web API

๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ œ๊ณตํ•˜๋ฉฐ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„ ์™ธ๋ถ€์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. Call Stack์—์„œ ๋น„๋™๊ธฐ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ, Web API๋กœ ์ž‘์—…์„ ์œ„์ž„ํ•˜๋ฉฐ ์ž‘์—… ์™„๋ฃŒ ํ›„ ์ฝœ๋ฐฑ์„ Task Queue ๋˜๋Š” Microtask Queue์— ๋„ฃ์–ด์ค€๋‹ค.
setTimeout(() => {}, 1000)
1์ดˆ ํ›„ ์ฝœ๋ฐฑ์„ Task Queue์— ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

Task Queue (Macro Task Queue)

Web API์—์„œ ์™„๋ฃŒ๋œ ๋น„๋™๊ธฐ ์ž‘์—…(์˜ˆ: setTimeout, setInterval, I/O)์˜ ์ฝœ๋ฐฑ์ด ๋Œ€๊ธฐํ•˜๋Š” ํ์ž…๋‹ˆ๋‹ค. (FIFO ๋ฐฉ์‹) ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ Call Stack์ด ๋น„์—ˆ์„ ๋•Œ Task Queue์—์„œ ์ž‘์—…์„ ๊ฐ€์ ธ์™€ ์‹คํ–‰ ํ• ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. Microtask Queue๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋‚ฎ์Šต๋‹ˆ๋‹ค.

Microtask Queue (๋งˆ์ดํฌ๋กœ ํ)

Promise์˜ .then, .catch, async/await, queueMicrotask ๋“ฑ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์ฝœ๋ฐฑ์ด ๋Œ€๊ธฐํ•˜๋Š” ํ์ž…๋‹ˆ๋‹ค. (FIFO ๋ฐฉ์‹) Task Queue์™€ ๋ณ„๋„๋กœ ๊ด€๋ฆฌ๋˜๋ฉฐ, Microtask๋Š” Call Stack์ด ๋น„์—ˆ์„ ๋•Œ ์ฆ‰์‹œ ์‹คํ–‰๋˜๋ฉฐ, Task Queue๋ณด๋‹ค ๋จผ์ € ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ํ•œ ๋ฒˆ์˜ "ํ‹ฑ(tick)"์—์„œ ๋ชจ๋“  Microtask๋ฅผ ์ฒ˜๋ฆฌํ•œ ํ›„ Task Queue๋กœ ๋„˜์–ด๊ฐ„๋‹ค. Heap์— ์ €์žฅ๋œ Promise ๊ฐ์ฒด๊ฐ€ ํ•ด๊ฒฐ(resolve)๋˜๋ฉด, ํ•ด๋‹น ์ฝœ๋ฐฑ์ด Microtask Queue๋กœ ์ด๋™ํ•œ๋‹ค.
console.log("Start");
setTimeout(() => console.log("Timeout"), 0);
Promise.resolve().then(() => console.log("Promise"));
console.log("End");
์ถœ๋ ฅ: Start โ†’ End โ†’ Promise โ†’ Timeout
์ด์œ : Microtask Queue(Promise)๊ฐ€ Task Queue(setTimeout)๋ณด๋‹ค ๋จผ์ € ์ฒ˜๋ฆฌ๋จ.

Event Loop (์ด๋ฒคํŠธ ๋ฃจํ”„)

Call Stack, Microtask Queue, Task Queue๋ฅผ ๊ฐ์‹œํ•˜๋ฉฐ ์ž‘์—…์„ ์ ์ ˆํžˆ ์Šคํƒ์œผ๋กœ ์ด๋™์‹œํ‚ต๋‹ˆ๋‹ค.

๐Ÿ“ ๋™์ž‘ ์ˆœ์„œ

  • Call Stack์ด ๋น„์—ˆ๋Š”์ง€ ํ™•์ธ.
  • Microtask Queue์— ์ž‘์—…์ด ์žˆ์œผ๋ฉด ๋ชจ๋‘ ์ฒ˜๋ฆฌ(Heap์—์„œ ๋ฐ์ดํ„ฐ ์ฐธ์กฐ).
  • Task Queue์—์„œ ์ž‘์—…์„ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด ์‹คํ–‰.
Heap์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ์™€ ํ์— ๋Œ€๊ธฐ ์ค‘์ธ ์ฝœ๋ฐฑ์„ ์—ฐ๊ฒฐํ•˜๋ฉฐ, ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์กฐ์œจํ•œ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋Ÿฐํƒ€์ž„ ์ „์ฒด ํ๋ฆ„

console.log("Start");
setTimeout(() => console.log("Timeout"), 0);
Promise.resolve().then(() => console.log("Promise"));
let obj = { message: "Heap" };
console.log(obj.message);

Heap

Heap: { message: "Heap" } ๊ฐ์ฒด๊ฐ€ Heap์— ์ €์žฅ๋˜๊ณ , obj๋Š” ์Šคํƒ์—์„œ ์ฐธ์กฐํ•œ๋‹ค.

Call Stack

  • console.log("Start") ์‹คํ–‰ ํ›„ ์ œ๊ฑฐ.
  • setTimeout ํ˜ธ์ถœ โ†’ Web API๋กœ ์ด๋™.
  • Promise.resolve().then ํ˜ธ์ถœ โ†’ Promise ๊ฐ์ฒด๋Š” Heap์—, .then ์ฝœ๋ฐฑ์€ Microtask Queue๋กœ.
  • console.log(obj.message) ์‹คํ–‰ ํ›„ ์ œ๊ฑฐ.

Web API

  • setTimeout์ด 0์ดˆ ํ›„ ์ฝœ๋ฐฑ์„ Task Queue์— ์ถ”๊ฐ€.

Event Loop

  • Call Stack ๋น„์—ˆ์Œ โ†’ Microtask Queue์—์„œ Promise ์ฝœ๋ฐฑ ์‹คํ–‰.
  • Task Queue์—์„œ Timeout ์ฝœ๋ฐฑ ์‹คํ–‰.

์ถœ๋ ฅ

Start โ†’ Heap โ†’ Promise โ†’ Timeout
์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์€ Call Stack์œผ๋กœ ๋™๊ธฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ณ , Heap์—์„œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉฐ, Web API, Task Queue, Microtask Queue, Event Loop๊ฐ€ ํ˜‘๋ ฅํ•˜์—ฌ ๋น„๋™๊ธฐ ์ž‘์—…์„ ํšจ์œจ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ Microtask Queue๋Š” Promise์™€ ๊ฐ™์€ ์ž‘์—…์„ ์šฐ์„  ์ฒ˜๋ฆฌํ•˜๋ฉฐ, Heap์€ ๋ชจ๋“  ๋ฐ์ดํ„ฐ์˜ ๊ธฐ๋ฐ˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ตฌ์กฐ ๋•๋ถ„์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” UI ๋ฐ˜์‘์„ฑ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ๋ณต์žกํ•œ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ด€๋ จ๊ฒŒ์‹œ๋ฌผ [์ด๋ฒคํŠธ ๋ฃจํ”„]: https://nam-yeun-hwa.github.io/posts/37