원시타입과 참조타입이 헷갈려 공부를 하다보니 콜스택, 힙, 가비지컬렉터의 개념이 필요한 것 같더라..
가비지컬렉터의 경우 원시 타입을 재할당 한 후 남는 데이터는 어떻게 되는거지? 궁금했는데 가비지컬렉터가 이를 해결해준다는 것을 알게 되었다.
====================================================================
JS는 프로그램이 실행될 때 세 개의 메모리 공간을 가진다.
Code Area : 실행할 JS 코드를 저장.
Call Stack : 지역 변수 저장. 변수들은 LIFO형식으로 저장. 원시 타입들이 이 곳에 저장된다.
Heap : 참조 타입들이 이 곳에 저장된다. 메모리 할당은 LIFO 형식을 따르지 않고 랜덤하게 들어간다. 메모리 누수 방지를 위해 JS 엔진의 메모리 관리자, 가비지컬렉터(Garbage Collector)가 항상 관리한다.
** LIFO(Last In First Out) : 가장 최근에 추가된 데이터가 가장 먼저 제거될 항목. 순서가 존재하는 프로세스.
원시타입 :
- 원시타입을 변수로 선언하게 되면 메모리공간에 변수명이 붙고 그 안에 할당한 값들이 들어간다.
- 하나의 데이터만 담기므로 재할당 시 재할당 된 값만 메모리 공간에 들어간다.
- 불변.
- 재할당 하거나 변수를 다른 변수에 저장할 때 값 자체가 새롭게 복사된다. (기존 값의 변형이 아니라 새로운 값이 됨)
- 객체가 아니면서 메소드도 가지지 않는 데이터
- string, number(en-US), bigint(en-US), boolean, undefined, symbol, null
let a = 'abc'; // 변수 a에 문자열 'abc' 할당
a= a + 'def'; // 변수 a에 문자열 'abcdef' 할당
// heap에 'abcdef' 데이터가 저장되고 변수 a에 할당되며,
// 'abc'데이터는 heap에서 더이상 쓰이지 않는 더미데이터가 되어
// JS에 내장되어 있는 가비지컬렉터(garbage collector)에 의하여 포집되어 삭제되고 메모리 용량이 확보된다.
let a2 = a; // a가 가리키는 heap주소를 a2에게 할당
a2 = 'hello'; // 'hello'라는 데이터를 heap에 생성한 후 이 주소를 a2에게 할당한다.
console.log(a); // 'abcdef'
// heap에는 'abcdef'와 'hello'가 저장되어 있는 상태이며, a와 a2는 각각 다른 주소를 가리키고 있기 때문에
// a2를 변경해도 a는 변하지 않는다.
let b = 5;
// 변수 b에 숫자 5 할당. 일단 컴퓨터가 heap(데이터영역)에서 5의 값을 찾고, 없으면 새로운 공간을 할당해 저장.
let c = 5;
// c에 숫자 5를 할당하기 위해서 heap에서 5를 찾아 해당 주소를 재활용 하여 할당.
참조타입 :
- 배열이나 객체 등에 해당된다.
- Array, Function, Date, RegExp, Map, WeakMap, Set, WeakSet
- 원시타입 데이터는 stack 영역에 메모리가 할당되어 하나의 데이터만 들어갈 수 있다. 그러나 참조타입은 배열이나 객체처럼 여러개의 값이 들어가야 하므로 heap 영역을 크게 만들어주고 stack영역에 heap영역의 주소값을 넣어 heap주소에 값을 연결해준다.
- 따라서 heap영역의 메모리 공간은 동적(dynamic)으로 크기가 변한다.
- 참조타입 데이터는 주소를 복사하기 때문에 주소 안의 데이터가 변경이 되어 기존의 데이터에도 영향이 간다.
let a = [1,2,3];
let b = a;
b[0] = 0; // b가 참조하는 heap주소의 데이터를 변경
console.log(b); // [0,2,3];
console.log(a); //[0,2,3]; a가 참조하는 heap주소는 b가 참조하는 heap주소와 동일하므로 a의 출력값도 변한다.
'개발 저장소 > 개발 지식 저장소' 카테고리의 다른 글
[React.js] props로 받은 배열을 동적 할당하기 (0) | 2022.12.12 |
---|---|
[React.js] 선언형 프로그래밍 vs 명령형 프로그래밍(공부 예약) (0) | 2022.12.10 |
[React.js] CSS 컴포넌트 활용하기(컴포넌트를 활용해 css중복 추출, 적용) (0) | 2022.12.09 |
[React.js] 컴포넌트에 props 전달하기 (0) | 2022.12.09 |
[Javascript] new Date(2022, 11, 09) 구문 사용 시 error!! (0) | 2022.12.09 |