JavaScript 프로그램은 컴퓨터에서 어떻게 실행될까?

스노어·2026년 1월 7일

CS

목록 보기
1/6
post-thumbnail

가장 먼저 "프로그램이 실행된다"는 말의 정확한 의미부터 정리해본다.

이 글은 Node.js를 활용한 웹서비스를 개발하면서
프론트엔드와 백엔드를 모두 이해하는
풀스택 개발자가 되기 위해 CS를 정리하는 첫 글이다.


💡 왜 이걸 알아야 할까?

JavaScript로 서버 코드를 작성하다 보면 이런 말을 자주 듣는다.

  • Node.js싱글 스레드
  • 이벤트 루프 덕분에 비동기가 가능하다
  • 메모리를 많이 쓰면 서버가 느려진다

하지만 정작
"JavaScript 코드는 컴퓨터에서 어떻게 실행되나요?"
라는 질문에는 막연해지기 쉽다.

그래서 CS 공부의 첫 단계로
프로그램 실행의 전체 흐름부터 정리해보려고 한다.


🖥️ 컴퓨터의 기본 구성 요소

컴퓨터를 사람의 몸에 비유하면 이렇다:

  • CPU = 뇌 (생각하고 계산함)
  • 메모리(RAM) = 작업 책상 (지금 하는 일을 펼쳐놓는 공간)
  • 저장장치(SSD) = 책장 (파일을 영구 보관)
구성 요소역할개발자 관점
CPU연산, 계산JavaScript 코드를 실제로 실행
메모리(RAM)임시 저장변수, 객체, 함수가 올라가는 공간
저장장치(SSD)영구 저장.js 파일이 저장된 위치

📌 핵심: 이 세 가지는 독립적으로 동작하는 게 아니라, 프로그램이 실행되는 과정에서 서로 긴밀하게 연결되어 동작한다.

📊 전체 실행 흐름 미리보기

┌─────────────┐
│ 저장장치(SSD) │ ← app.js 파일 저장
└──────┬──────┘
       │ ① OS가 파일 읽기
       ↓
┌─────────────┐
│  메모리(RAM)  │ ← 코드가 적재됨
│  + Node.js   │
│  + V8 엔진   │
└──────┬──────┘
       │ ② V8 엔진이 변환
       ↓
┌─────────────┐
│     CPU     │ ← 실제 실행
└─────────────┘

이제 이 과정을 하나씩 자세히 살펴보자.


⚙️ "프로그램을 실행한다"의 정확한 의미

터미널에서 다음 명령어를 실행한다고 가정해보자.

node app.js

🤔 이 한 줄이 실행되면 뒤에서 무슨 일이 일어날까?


1️⃣ 단계: OS가 파일을 찾아 읽는다

💬 운영체제(OS) 란?
Windows, macOS, Linux 같은 프로그램들을 관리하는 기본 시스템이다.

운영체제디스크(SSD)에서 app.js 파일을 찾아 읽어들인다.
이 시점에는 아직 텍스트 파일 그대로다.

💾 디스크(SSD)
└── app.js (텍스트 파일)[OS가 읽음]

쉽게 말하면: 책장에서 책을 꺼내는 과정이다.


2️⃣ 단계: 파일 내용을 메모리에 적재한다

OS가 읽어온 app.js 파일의 내용을 메모리(RAM)에 올린다.
이제 프로그램이 메모리 공간을 차지하게 된다.

🧠 메모리(RAM)
├── app.js 코드 내용
├── Node.js 런타임
└── V8 엔진

쉽게 말하면: 책장에서 꺼낸 책을 책상 위에 펼쳐놓는 과정이다.


3️⃣ 단계: Node.js와 V8 엔진이 코드를 변환한다

💬 V8 엔진 이란?
Google에서 만든 JavaScript 실행 엔진으로, Chrome 브라우저와 Node.js가 사용한다.

메모리에 올라온 JavaScript 코드를 V8 엔진이 처리한다.
이 과정은 3단계로 나뉜다.


3-1. 파싱(Parsing): 코드 구조 분석

💬 파싱(Parsing) 이란?
코드를 읽고 문법 구조를 분석하는 과정이다.

const user = { name: "Kim" };

위 코드를 V8 엔진이 읽고
AST(추상 구문 트리) 라는 구조로 변환한다.

💬 AST(Abstract Syntax Tree) 란?
코드를 나무 구조로 표현한 것이다.
마치 문장을 주어-동사-목적어로 분석하는 것과 비슷하다.

AST (추상 구문 트리)
├── 변수 선언: const
├── 변수명: user
└── 값: 객체 { name: "Kim" }

3-2. 바이트코드로 변환

💬 Ignition(이그니션) 이란?
V8 엔진의 인터프리터로, 코드를 빠르게 실행할 수 있는 중간 형태로 변환한다.

AST를 기반으로 V8 엔진의 Ignition
JavaScript 코드를 바이트코드로 변환한다.

JavaScript 코드
    ↓
바이트코드 (중간 언어)

바이트코드CPU가 직접 이해할 수는 없지만,
사람이 작성한 코드보다는 기계에 가까운 형태다.

📌 마치 영어를 한국어로 번역하는 중간에 '콩글리시'를 만드는 것과 비슷하다.


3-3. 머신 코드로 최적화

💬 Hot Code(핫 코드) 란?
자주 실행되어 '뜨거워진' 코드를 의미한다.

자주 실행되는 코드는 V8의 TurboFan(JIT 컴파일러)
머신 코드(기계어) 로 변환한다.

💬 JIT(Just-In-Time) 컴파일러 란?
코드를 실행하는 순간에 컴파일하는 방식이다.
미리 전체를 번역하는 게 아니라, 필요한 부분만 빠르게 번역한다.

바이트코드
    ↓
머신 코드 (CPU가 직접 실행 가능)

머신 코드는 CPU가 바로 이해하고 실행할 수 있는 0과 1로 된 언어다.


4️⃣ 단계: CPU가 명령을 실행한다

최종적으로 변환된 머신 코드CPU가 한 줄씩 실행한다.

CPU
├── 변수 user를 메모리 Heap에 할당
├── name 속성에 "Kim" 저장
└── 다음 명령 대기

쉽게 말하면: 책상에 펼쳐진 책을 보고 실제로 문제를 푸는 과정이다.


🔄 전체 흐름 요약

1. [디스크] app.js 파일 저장됨
         ↓
2. [OS] 파일을 읽어 메모리로 로드
         ↓
3. [메모리] 코드가 RAM에 적재됨
         ↓
4. [V8 엔진]
   ├─ Parsing: 코드를 AST로 변환
   ├─ Ignition: AST를 바이트코드로 변환
   └─ TurboFan: 자주 쓰는 코드를 머신 코드로 최적화
         ↓
5. [CPU] 머신 코드를 실행

📌 핵심 정리
프로그램 실행이란 디스크메모리V8 변환CPU 실행으로 이어지는 과정이다.


🔀 컴파일 언어 vs 인터프리터 언어

프로그래밍 언어는 실행 방식에 따라 나눌 수 있다.

구분컴파일 언어인터프리터 언어
예시C, JavaJavaScript (전통적)
실행 방식미리 전체 번역한 줄씩 해석
실행 파일생성됨 (.exe)없음
실행 시점컴파일 후코드 실행할 때마다
비유책 전체를 번역한 후 읽기동시통역하며 읽기

🤔 JavaScript는 어느 쪽일까?

전통적으로는 인터프리터 언어였지만,
현대의 V8 엔진JIT(Just-In-Time) 컴파일 방식을 사용한다.

전통적 인터프리터: 
코드 → 한 줄씩 실행 (느림 🐌)

V8 엔진 (JIT): 
코드 → 바이트코드 → 머신 코드 → 실행 (빠름 🚀)

✨ 이 차이 덕분에 Node.js는 인터프리터 언어인 JavaScript를 서버 환경에서도 충분한 성능으로 실행할 수 있다.


🌟 Node.js와 V8 엔진


V8 엔진의 역할

V8 엔진은 JavaScript 코드를 단순히 한 줄씩 해석만 하는 것이 아니라:

1. 파싱: 코드를 AST로 변환
2. 바이트코드 생성: Ignition이 중간 코드 생성
3. 최적화: TurboFan이 자주 쓰는 코드를 머신 코드로 변환

그래서 Node.js는 인터프리터 언어임에도 불구하고 비교적 빠른 성능을 낼 수 있다.


Node.js는 V8만이 아니다

💬 Node.js 런타임 이란?
JavaScript 코드를 실행할 수 있는 전체 환경을 의미한다.

Node.js는 단순히 V8 엔진만을 의미하지 않는다.

📦 Node.js 런타임
├── V8 엔진 (JavaScript 실행)
└── Node APIs
    ├── libuv (비동기 I/O 처리)
    ├── fs (파일 시스템)
    ├── http (네트워크)
    └── setTimeout (타이머)

Node.js

  • JavaScript 코드를 실행하는 V8 엔진
  • 파일 시스템, 네트워크, 타이머 같은 비동기 작업을 운영체제에 위임하기 위한 Node APIs(libuv)

를 함께 포함한 하나의 실행 환경이다.


📌 정리하면
Node.jsJavaScript를 운영체제(OS) 위에서 빠르게 실행하기 위한 런타임 환경이다.

그래서 Node.js

  • 브라우저 없이도 JavaScript를 실행할 수 있고
  • 웹 서버, CLI 도구, 백엔드 애플리케이션 개발에 활용된다

🧠 메모리는 왜 중요한가?

다음과 같은 JavaScript 객체를 떠올려보자.

const user = {  
  name: "Kim",  
  age: 30  
};

이 객체는 디스크에 저장되는 것이 아니라 메모리(RAM)에 저장된다.


메모리의 구조

프로그램이 실행되는 동안 데이터는 항상 메모리에 올라가며,
JavaScript 실행 과정에서는 메모리가 역할에 따라 나뉜다.

🧠 메모리(RAM)
├── Call Stack
│   └── 함수 호출 정보 (실행 순서)
│
└── Heap
    └── 객체와 데이터 (user, 배열 등)

📚 Call Stack (호출 스택)

💬 Call Stack 이란?
함수가 어떤 순서로 실행되는지 기록하는 공간이다.
마치 책을 차곡차곡 쌓아놓는 것과 비슷하다.

function greet() {
  console.log("Hello");
}
greet();
Call Stack 상태
[greet] ← 현재 실행 중
[전역]

📦 Heap (힙)

💬 Heap 이란?
객체, 배열 같은 실제 데이터가 저장되는 공간이다.
크기가 큰 데이터를 자유롭게 보관하는 창고와 비슷하다.

const user = { name: "Kim" };
Heap 상태
{ name: "Kim" } ← 메모리 주소: 0x1234

🎯 메모리를 이해해야 하는 이유

이 메모리 구조를 이해하지 못하면 다음과 같은 개념들을 제대로 이해하기 어렵다:

개념메모리와의 관계
이벤트 루프Call Stack과 Callback Queue의 관계
비동기 처리setTimeout이 Stack에서 빠져나가는가
서버 성능 저하Heap 메모리가 부족하면 발생
메모리 누수사용하지 않는 객체가 Heap에 남아있는 경우

⚠️ 이러한 개념들은 모두 메모리를 어떻게 사용하느냐와 직접적으로 연결되어 있다.


🎓 마무리 정리

💻 node app.js 실행
    ↓
1. OS가 app.js를 디스크에서 읽음
    ↓
2. 파일 내용을 메모리(RAM)에 적재
    ↓
3. V8 엔진이 변환 작업 수행
   ├─ Parsing (AST 생성)
   ├─ Ignition (바이트코드 변환)
   └─ TurboFan (머신 코드 최적화)4. CPU가 머신 코드를 한 줄씩 실행
    ↓
5. 결과가 Node.js 메모리(Stack/Heap)에 저장됨
   ├─ Stack: 지역변수, 함수 호출 스택
   └─ Heap: 객체, 배열, 문자열 데이터

✅ 기억할 것

  • JavaScript 코드는 운영체제 위에서 실행된다
  • Node.js는 CPU가 JavaScript를 실행하도록 돕는 런타임 환경이다
  • 프로그램 실행은 디스크메모리V8 변환CPU 흐름이다
  • V8은 코드를 바이트코드머신 코드로 변환해 성능을 높인다
  • 이 흐름을 이해해야 비동기와 이벤트 루프를 이해할 수 있다

👉 다음 글에서는 Stack / Heap 구조를 자세히 다룰 예정이다.

  • Call Stack은 어떻게 동작하는가?
  • Heap에 데이터는 어떻게 저장되는가?
  • 메모리 누수는 왜 발생하는가?
profile
눈코딩 재밌게 합시다!

0개의 댓글