자바스크립트의 메모리 구조

Creating the dots·2022년 1월 17일
2

CS

목록 보기
14/19
  • 자바스크립트는 소스코드를 2단계로 나누어 실행하는데, 먼저 선언문을 찾아 변수를 실행 컨텍스트의 렉시컬 환경에 등록하고, 소스코드를 실행하며(런타임) 값을 할당하고 참조한다.
  • 원시타입의 데이터는 콜스택에 저장되고, 참조타입은 메모리 힙에 저장된다.

원시타입 데이터 저장하기

let myNumber = 23;
  1. 자바스크립트는 코드를 훑으며 키워드 let, var, const 등으로 변수 또는 함수 등을 발견한다. (런타임 이전)
  2. myNumber라는 변수 식별자가 생성되고, 실행환경의 렉시컬 환경에 저장된다.
  3. 원시타입의 데이터 값은 콜스택에 저장되는데, myNumber에는 콜스택의 주소값이 저장되고, 콜스택에는 데이터(23)가 저장된다. (런타임)

👉 우리가 선언한 변수에는 콜스택 주소값이 저장된다.

👉 원시타입 데이터는 런타임때 콜스택에 저장된다.

🙋 만약 값을 복사한다면?

let myNumber = 23;
let newVar = myNumber;

👉 myNumber와 newVar에는 같은 콜스택 주소값이 할당된다.

👉 값을 복사하거나, 같은 값을 가진다면, 콜스택의 새로운 주소를 할당받는 것이 아니라 같은 주소를 갖는다는 것!

🙋 만약 값을 재할당한다면?

같은 콜스택 주소값을 가지고 있은 식별자들이 여러개가 있을 수 있는데, 만약 그 중 하나라도 값이 변경되면, 나머지 콜스택 주소를 참조하는 값들도 다 변경되어야할까?

myNumber = myNumber + 1;
  1. 23+1 = 24가 된다.
  2. myNumber는 새로운 콜스택 주소값을 할당받는다.
  3. newVar는 여전히 기존 콜스택 주소값이 할당되어있다.

👉 같은 주소값을 참조하고 있는 식별자들 중 하나가 데이터가 변경되면, 그 식별자는 새로운 주소값을 할당받는다.

👉 만약 더이상 어느 식별자도 콜스택 주소값을 사용하고 있지 않으면 이때 가비지 콜렉터가 실행된다.

참조타입 데이터 저장하기

let myArray = [];
  1. 자바스크립트는 코드를 훑으며 키워드 let, var, const 등으로 변수 또는 함수 등을 발견한다. (런타임 이전)
  2. myArray라는 변수 식별자가 생성되고, 실행환경의 렉시컬 환경에 저장된다.
  3. myArray에는 콜스택의 주소값이 저장되고, 콜스택에는 힙의 주소값이 저장되고, 힙의 해당 주소에는 데이터([])가 저장된다. (런타임)

🙋 만약 데이터를 동적으로 변경하면?

myArray.push("first");
myArray("second");
myArray("third");
myArray("fourth");
myArray.pop();

👉 원시타입과 다르게 참조타입의 데이터는 메모리 힙에 저장된다. 따라서, push, pop 등으로 저장된 값을 변경하더라도, 첫째, 배열이 저장된 메모리힙의 주소는 변경되지 않고, 둘째, 콜스택에 저장된 메모리힙의 주소도 변경되지 않고, 셋째, 식별자에 할당된 콜스택의 주소도 변경되지 않는다.

🔍 const는 재할당이 안된다고 했는데 배열과 객체의 데이터 변경이 가능한 이유는?
const는 재할당이 안된다. 여기서 재할당이란, 새로운 주소값을 할당받는 것을 말한다. const로 선언된 배열과 객체를 변경할때, 메모리힙의 주소값이 변경되지 않으므로 콜스택 주소값도 변경되지 않는다. 데이터를 변경했으니까 재할당이 되는 것 아니야?라고 생각할 수 있지만, 여전히 같은 콜스택 주소를 가리키고, 같은 메모리힙 주소를 가리키므로, 데이터의 변경은 재할당이 아니다!

🙋 만약 재할당하면?

바로 위에서 재할당이란, 새로운 주소값을 할당받는 것이라고 했다. 그리고 const 키워드로 선언한 데이터는 재할당이 불가능하다.

다음 예시를 살펴보도록 하자.

const myArray = [];
myArray = 3;

👉 myArray는 참조타입이므로 메모리 힙에 빈배열이 저장되었다.

👉 myArray에 3을 재할당하려고 하면, 3은 원시타입이므로 식별자 myArray에는 새로운 콜스택 주소값을 할당하고, 3을 저장하려고 할 것이다. 그런데, 이미 식별자 myArray에는 콜스택 주소값이 할당되어있으므로 재할당할 수 없다는 에러가 발생할 것이다.

reference

profile
어제보다 나은 오늘을 만드는 중

0개의 댓글