JavaScript 데이터 - CallStack/MemoryHeap 구조, 데이터 저장/참조 원리

2022. 2. 21. 11:23공부/Javascript

[자바스크립트] 콜스택/메모리힙 구조, 데이터 저장/참조 원리 (tistory.com)

 

[자바스크립트] 콜스택/메모리힙 구조, 데이터 저장/참조 원리

이 글은 자바스크립트의 콜스택/메모리힙에서 데이터가 어떤 방식으로 저장되고 참조되는지를 정리한다. 기본적인 메모리 구조와 변수 생성 원리에 대해서는 아래 글을 꼭 참고(필수) [자바스

curryyou.tistory.com

상위 블로그 글 백업용.

 

콜스택(CallStack)

- 원시타입(숫자, 문자 등) 데이터가 저장된다.

- 실행컨텍스트(Execution Context)를 통해 1) 변수 식별자(이름) 저장, 2) 스코프 체인 및 this 관리, 3) 코드실행순서 관리

메모리힙(MemoryHeap)

- 참조타입(객체 등) 데이터가 저장된다.

콜스택, 메모리힙의 데이터 구조

: 원시타입은 콜스택, 참조타입은 메모리힙에 저장된다.

 

변수식별자 a, b, c, d 자체는 콜스택 상의 '실행컨텍스트(Execution Context)의 렉시켤 환경(Lexical Environment)' 에 저장된다.

 

원시타입의 변수 데이터

1. 원시타입 변수 생성

- 데이터 값은 콜스택에 저장되고 콜스택의 주소값은 변수 a, b에 저장된다. a, b는 실행컨텍스트의 렉시컬 환경에 저장.

2. 원시타입 재할당 - Case 1

- 본인 메모리에 있는 값을 변경하는 것이 아니라 기존에 저장하고 있던 다른 메모리의 주소값으로 교체한다.

- a 와 b가 가리키는 주소값은 동일해진다.

3. 원시타입 재할당 - Case 2

- 새로운 메모리를 확보하여 저장하고, 변수 b에 저장되어있던 주소값을 교체한다.

4. 가비지 컬렉터

: 더 이상 참조되지 않는 데이터는 적절한 시점에 가비지 컬렉터에 의해 메모리에서 해제된다.

 

참조타입의 변수 데이터

1. 참조타입 변수 생성

- 배열과 같은 참조타입 데이터는 메모리 힙에 저장된다.

- 메모리 힙의 주소값은 콜스택에 저장되고, a와 b에는 해당 콜스택의 주소값이 저장된다.

(a는 const, b는 let으로 선언된 것을 기억)

2. 참조타입 데이터의 값 변경

- 변수에 값을 재할당한게 아니라, 변수에 저장된 데이터를 수정한 것.

- 메모리힙에 저장된 배열의 값을 변경해도 배열이 저장된 메모리 힙의 주소는 동일하다.

- 콜스택에 저장된 메모리 힙의 주소는 변하지 않음. 사실상 a와 b는 변한게 없는 셈.

- 따라서 재할당이 필요없는 경우, 참조타입은 const로 선언하는게 좋다.

 

3. 참조타입 재할당

1) let으로 선언된 참조타입의 재할당.

- 메모리 힙에 새로운 주소가 확보되고, 새로운 배열이 저장된다..

- 콜스택에 저장되는 메모리힙의 주소값도 새로운 주소값으로의 변경이 필요한데 이 때 콜스택에도 새로운 메모리를 확보한 후 그곳에 새로운 메모리힙 주소값을 저장한다.

- 따라서 변수 b에 저장되는 콜스택의 주소값도 변경된다.

2) const로 선언된 참조타입의 재할당. (실행 불가능)

- const는 변수에 저장된 주소값을 변경하지 못하게 막는 키워드이다.

- 새로운 참조타입을 재할당하게 되면 콜스택에 저장된 변수의 주소값도 변경해야 하므로 에러가 발생하게된다.

(const로 선언할 때는 반드시 초기값을 할당하면서 선언해야 한다.)

4. 동일한 구성의 참조타입 데이터

- 참조타입 객체는 동적으로 내부 요소가 변경될 수 있으므로, 동일한 요소의 객체를 생성하더라도 메모리힙에 별도의 메모리 공간을 확보하여 저장하게 된다.

- 따라서 me !== you 이다.

정리)

JavaScript는 변수 선언 시 2단계로 나누어 실행한다.

1. 선언문들을 찾아 변수 등을 실행 컨텍스트의 렉시컬 환경에 등록하는 과정

2. 소스코드를 첫 줄 부터 차례로 실행하며 값을 할당하고 참조한다.