References

https://developer.mozilla.org/ko/docs/Web/JavaScript/Memory_Management

https://ui.toast.com/weekly-pick/ko_20210611

https://engineering.huiseoul.com/자바스크립트는-어떻게-작동하는가-메모리-관리-4가지-흔한-메모리-누수-대처법-5b0d217d788d

https://velog.io/@bumsu0211/JavaScript-Garbage-Collection https://blockdmask.tistory.com/290

 

가비지 컬렉션(Garbage Collection)의 대두

동적 메모리의 관리는 기본적으로 할당해제, 두 과정이 필요하다.

C언어의 경우 malloc과 free함수로 이를 수동 처리 해야 했는데 대략적인 과정은 다음과 같다.

#include<stdio.h>
#include<stdlib.h>

int main(void) {
    int arr[4] = { 4,3,2,1 }; // 크기가 4인 배열 선언
    int* pArr; // int 타입을 가리키는 포인터 pArr 선언

    // malloc 내장 함수를 통해 int 타입사이즈 * 4 만큼의 메모리를 할당
    pArr = (int *)malloc(sizeof(int) * 4);
		
		... 중략

    // free 내장 함수를 통해 할당한 메모리를 해제
    free(pArr);

    system("pause");
    return 0;
}

이로 인해 메모리 관리를 전적으로 개발자가 부담해야 했고 개발 규모가 커짐에 따라 그만큼 개발 부담이 오는 단점이 생겨났다.

그러한 이유로 이 후 생겨난 **고 레벨 언어(Java, Python, Javascript)**에서는 이러한 과정들을 자동화 시켰는데, 그것이 바로 가비지 컬렉션이다.

 

자바스크립트의 가비지 컬렉션

자바스크립트에서의 변수는 크게 Primitive TypeObject Type 두 종류가 존재한다.

Primitive Type

integer, string, boolean, null, undefined, symbol 타입들을 지칭한다.

primitive type은 기본적으로 immutable data의 특성을 가지고 있어 한 번 할당 받으면 값이 변경되지 않기 때문에 값을 재할당 하게 되면 새로운 메모리 공간에 값을 넣어 해당 주소로 변경한다. 이 후 이전 값은 더 이상 사용되지 않기 때문에 가비지 컬렉션에 의해 메모리가 해제된다.

// number 타입의 변수 초기화 및 값 할당
let num = 1;

// 이 후, 값을 재할당하게 되면 새로운 메모리 공간에 값이 추가되어 주소가 변경된다
num = 2;

Object Type

**primitive type을 제외한 나머지들(object, array, function 등)**을 지칭한다.

object 타입의 경우 변수에 할당을 하게 되면 변수에는 실제 객체가 저장된 힙 메모리 주소가 저장된다.

const person = {
  name: 'Lee'
}

이 후, 객체 타입을 담은 변수를 다른 변수에 할당하면, 메모리 주소를 공유하기 때문에 같은 객체를 가리킨다.

const p1 = person
console.log(p1 === person) // true

단, **객체를 복사해서 새로운 변수에 할당(얉은 복사)**하면, 값이 같아도 메모리 주소가 다르기 때문에 서로 다른 객체가 된다.

// 스프레드 연산자를 통해 person 객체를 복사
const p2 = { …person }
console.log(p2 === person) // false

이러한 이유로 메모리 주소를 통하는 방법을 통해(포인터) 객체에 접근을 하게 되는데, 만약 객체를 가리키는 포인터가 하나도 없으면 이는 가비지 컬렉션의 대상이 된다.

 

자바스크립트 가비지 컬렉션의 종류

Reference-Counting

참조 하는(Reference) 개수를 **카운팅(Counting)**하여 하나도 없으면 이를 가비지로 판단하는 방법

Mark-and-Sweep

가비지를 닿을 수 없는 노드(메모리)로 정의하여, roots라는 전역변수 집합부터 시작해 이를 참조하는 객체들을 세대 별로 탐색하여 최종적으로 접근할 수 없는 객체들을 선별 후 이를 가비지로 판단한다.

https://t1.daumcdn.net/cfile/tistory/997FE9375DDCC3920C

'Self-Study > Javascript' 카테고리의 다른 글

[Javascript] 데이터 바인딩의 이해  (0) 2022.10.13
[Javascript] ES2022 기능 요약  (0) 2022.08.24
[Javascript] console.log depth 출력  (0) 2022.07.04
[Javascript] polling  (0) 2022.07.04
[Javascript] optional chaining  (0) 2022.07.04