728x90
반응형
SMALL

실행 컨텍스트와 스택 메모리
실행 컨텍스트는 스택 메모리에 저장됩니다.
function outer() {
let x = 10; // outer의 스택
function inner() {
let y = 20; // inner의 스택
}
inner();
}
outer();
콜 스택 (Call Stack):
┌─────────────────┐
│ inner 실행 컨텍스트 │ ← 현재 실행 중
│ - y: 20 │
├─────────────────┤
│ outer 실행 컨텍스트 │
│ - x: 10 │
├─────────────────┤
│ 전역 실행 컨텍스트 │
└─────────────────┘
실행 컨텍스트의 메모리 구성
function example() {
let num = 42; // 스택
let obj = { x: 1 }; // 스택(주소) + 힙(객체)
}
example();
실행 컨텍스트 생성 시:
콜 스택
┌──────────────────────┐
│ example 실행 컨텍스트 │
│ │
│ 렉시컬 환경: │
│ 환경 레코드 │
│ ┌────────┬────────┐ │
│ │ num │ 0x100 │ │ ──→ [스택 0x100]: 42
│ │ obj │ 0x200 │ │ ──→ [스택 0x200]: 0x5000 ──→ [힙 0x5000]: { x: 1 }
│ └────────┴────────┘ │
│ │
│ 외부 렉시컬 환경 참조 │
└──────────────────────┘
스택과 힙의 역할
스택 메모리
- 실행 컨텍스트 저장 ✅
- 렉시컬 환경 (환경 레코드)
- 원시값
- 객체의 참조(주소)
힙 메모리
- 실제 객체 저장 ✅
- 배열, 함수, 객체 등
- 실행 컨텍스트와는 별개
상세 예시
const global = 'global';
function outer() {
const outerVar = 10;
const outerObj = { value: 1 };
function inner() {
const innerVar = 20;
console.log(outerObj.value);
}
return inner;
}
const closure = outer();
closure();
메모리 구조:
콜 스택 (실행 컨텍스트들)
┌─────────────────────────┐
│ inner 실행 컨텍스트 │
│ 환경 레코드: │
│ - innerVar: 20 (스택) │
│ 외부 참조 → outer 환경 │
├─────────────────────────┤
│ (outer는 이미 종료) │
│ 하지만 클로저로 유지됨: │
│ 환경 레코드: │
│ - outerVar: 10 (스택) │
│ - outerObj: 0x5000 (스택)│ ──→ [힙 0x5000]: { value: 1 }
└─────────────────────────┘
함수 호출과 스택
function first() {
let a = 1;
second();
}
function second() {
let b = 2;
third();
}
function third() {
let c = 3;
}
first();
콜 스택 변화:
1. first() 호출
┌─────────────┐
│ first │
│ a: 1 │
├─────────────┤
│ 전역 │
└─────────────┘
2. second() 호출
┌─────────────┐
│ second │
│ b: 2 │
├─────────────┤
│ first │
│ a: 1 │
├─────────────┤
│ 전역 │
└─────────────┘
3. third() 호출
┌─────────────┐
│ third │
│ c: 3 │
├─────────────┤
│ second │
│ b: 2 │
├─────────────┤
│ first │
│ a: 1 │
├─────────────┤
│ 전역 │
└─────────────┘
4. third() 종료
┌─────────────┐
│ second │
│ b: 2 │
├─────────────┤
│ first │
│ a: 1 │
├─────────────┤
│ 전역 │
└─────────────┘
5. 모두 종료
┌─────────────┐
│ 전역 │
└─────────────┘
클로저와 힙 메모리
function createCounter() {
let count = 0; // 스택
const data = { x: 1 }; // 힙
return function() {
count++;
data.x++;
return { count, x: data.x };
};
}
const counter = createCounter();
메모리 상태:
스택 (클로저로 유지)
┌────────────────────┐
│ createCounter 환경 │
│ - count: 0 │
│ - data: 0x5000 │ ──→ [힙 0x5000]: { x: 1 }
└────────────────────┘
↑
│
counter 함수의
[[Environment]]가 참조
가비지 컬렉션
function example() {
let obj1 = { value: 1 }; // 힙에 생성
let obj2 = { value: 2 }; // 힙에 생성
return obj1; // obj1만 반환
}
const result = example();
함수 종료 후:
스택
┌──────────┐
│ (example │ ← 실행 컨텍스트 제거
│ 종료) │
└──────────┘
힙
[0x5000]: { value: 1 } ← result가 참조, 유지 ✅
[0x6000]: { value: 2 } ← 참조 없음, GC 대상 ♻️
정리
실행 컨텍스트와 메모리의 관계:
실행 컨텍스트 (콜 스택에 저장)
├─ 렉시컬 환경
│ ├─ 환경 레코드 (스택)
│ │ ├─ 원시값 → 스택에 직접
│ │ └─ 객체 → 스택에 주소, 힙에 실제 객체
│ └─ 외부 렉시컬 환경 참조
└─ this 바인딩
핵심:
- ✅ 실행 컨텍스트는 스택에 저장
- ✅ 렉시컬 환경(환경 레코드)도 스택
- ✅ 원시값은 스택에 직접
- ✅ 객체는 힙에, 주소만 스택에
- ✅ 실행 컨텍스트 종료 시 스택 정리
- ✅ 힙의 객체는 참조가 있으면 유지 (클로저)
// 요약
실행 컨텍스트 → 콜 스택 (스택 메모리)
원시값 → 스택 메모리
객체 → 힙 메모리 (주소는 스택)
완벽하게 연결되어 있습니다! 🎯
728x90
반응형
LIST
'javascript' 카테고리의 다른 글
| 함수 선언문과 실행 컨텍스트: 메모리 관점에서 이해하기 (0) | 2026.01.26 |
|---|---|
| 객체 메서드: 축약형 vs 일반형 차이점 (0) | 2026.01.26 |
| JavaScript 메모리 구조: 스택과 힙 (0) | 2026.01.25 |
| JavaScript 메모리 이해하기: 값 전달 vs 참조 전달 (0) | 2026.01.25 |
| 해시 테이블과 JavaScript 객체 (0) | 2026.01.25 |
댓글