자바스크립트 엔진
이 구동되면서 코드를 읽고 실행하는 과정에서 중요하게 여겨지는 2 가지 단계:
- 변수, 함수 등의 정보를 특정한 장소에 저장하는 것
- 현재 실행되고 있는 코드를 트래킹하는 작업
여기서 정보를 저장하는 공간이 Memory Heap이고, 실행 중인 코드를 트래킹하는 공간이 Call Stack
// test1 - 1
// 각각의 식별자가 같은 메모리 주소 가리킴
let num = 26;
let newNum = num;
console.log(num, newNum); // 26 26
// test1 - 2
num += 1;
console.log(num, newNum); // 27 26
// test2
let myString = "cat"
myString = myString + "love"
- 변수의 고유 식별자 "num" 생성
- 메모리에 주소 할당
- 생성된 주소에 값 저장
test1 - 2
에서 num + 1
의 연산 결과가 확인되면 자바스크립트는 메모리에 새로운 주소를 할당하므로 num, newNum은 각각 다른 주소를 가리키게 됨test2
에서 myString
은 기존에 가리키던 메모리 주소 대신 catlove
가 저장된 새로운 메모리 주소를 가리킴변경불가능(immutable)
하므로 이렇게 동작객체, 배열, 함수 등 크기가 동적으로 변할 수 있는 참조 타입 값을 저장
쉽게 말하면, Memory Heap이라는 창고 속에 겉에 이름이 라벨지로 붙어 있는 참조 타입 값의 박스가 있는 것
Memory Heap이 제대로 관리되지 않아 메모리 공간의 범위를 넘어서서 정보들이 저장되는 경우
과거에 사용되었고, 현재 필요 없는 데이터가 공간을 차지하고 있는 현상
가장 흔한 3가지 패턴
- 원시 타입 값 저장
- 함수 호출의 실행 컨텍스트(Execution Context)를 저장
function foo() {
foo();
}
foo();
작업이 수행되어 제거되지 않고 Call Stack에 쌓여 한정된 공간의 크기를 넘어서게 되는 경우
let a = 10;
let b = 35;
let arr = [];
function func() {
const c = a + b;
const obj = { d: c };
return obj;
}
let o = func();
Call Stack과 Memory Heap의 공간은 언제나 한정적이므로 이를 효율적으로 관리하기 위해서 더 이상 효용가치가 없다고 판단되는 변수, 함수 등을 실행 종료 후 Memory Heap에서 제거하는 동작을 수행해 주는 도구
// good
let sum = 0;
sum = 1 + 2 + 3 + 4 + 5;
// bad
let numbers = [];
numbers.push(1);
numbers.push(2);
numbers.push(3);
numbers.push(4);
numbers.push(5);
변경은 메모리 주소의 변경을 뜻함
const myArray = [];
myArray = 3; //원시타입 할당 불가
myArray = ["a"]; //새로운 배열 할당 불가
let과 const의 중요성
- 미래의 버그를 사전에 방지한다.
- const를 통해 선언된 변수는 반드시 선언과 동시에 초기화되어야하며, 이를 통해 개발자는 스코프적인 측면에서 더욱 신중하게 변수를 배치해야함을 강요받게 됩니다. 이는 궁극적으로 더 나은 메모리 관리 및 성능으로 이어지게됩니다.
- 단지 코드를 보는 것만으로도 어떤 변수가 변경 불가능하고, 또 어떤 변수가 재할당이 가능한지 의사소통할 수 있기 때문입니다.
콜 스택(Call stack)과 힙(Heap)
자바스크립트 런타임 : 콜스택과 메모리 힙
[JS] 자바스크립트 동작 원리(콜 스택, 콜백 큐, 이벤트 루프)
<번역>자바스크립트의 메모리 모델
[자바스크립트] 콜스택/메모리힙 구조, 데이터 저장/참조 원리
MDN 호출 스택