가지비 컬렉터 (GC)

  • c와 같은 언어에는 malloc()나 free()와 같은 저수준의 메모리 관리를 위한 함수가 존재한다. 개발자들은 명시적으로 운영체제로부터 메모리를 할당 받거나 돌려주는 작업을 해야한다.

  • 자바스크릅트에서는 객체나 문자열등이 생겨날 때 메모리가 할당되며 더 이상 사용되지 않을때는 자동으로 메모리가 반환되는데, 이 과정을 가비지 컬렉션이라고 한다.

메모리

메모리 정의

여러 개의 비트로 구성된 커다란 하나의 배열

  • 하드웨어 수준에서, 컴퓨터 메모리는 수 많은 flip-flop으로 구성되어 있다. flip-flop은 몇 개의 트랜지서트를 가지고 있고 하나의 비트를 저장할 수 있다.
  • 개별 flip-flop은 고유 식별자를 통해 위치를 확인할 수 있어서 사용자가 메모리를 읽거나 쓸 수 있다.

메모리 생명주기

메모리 할당

  • 프로그램이 사용할 수 있도록 운영체제가 메모리를 할당
  • 자바스크립트는 변수 할당 시점에서 메모리 할당을 스스로 수행

메모리 사용

  • 프로그램이 실제로 메모리를 사용하는 단계

메모리 해제

  • 프로그램에서 필요하지 않은 메모리 전체를 되돌려주는 과정
  • 고수준 언어에는 가비지 컬렉터가 내장되어 있다. 가비지 컬렉터는 메모리 할당을 추적하고 할당된 메모리가 더 이상 사용되지 않을때 자동으로 메모리에서 해제 시키는 역할을 한다.

가비지 컬렉션 알고리즘

메모리 참조 카운팅

  • 객체를 참조하는 대상이 하나도 없는 경우 GC대상으로 간주하고 메모리에서 해제 시킨다.
let obj = {

  a : { 
    b: 2
  } 
} // obj가 객체 {a { b: 2}}를 참조

let obj2 = obj // obj2도 {a { b: 2}}를 참조 
obj = 1; // obj에 1을 할당, obj2는 기존의 {a { b: 2}}를 그대로 참조하고 있어서 GC대상 아님
obj2 = 1 // obj2에도 1을 할당하면서, {a { b: 2}}를 참조하는 어떤 객체도 없어서 GC 대상이 됨(메모리 해제)

순환참조 문제

a,b는 아무 의미가 없어서 GC대상이 되어야 하지만 ,a,b가 서로 참조를 하고 있는 상황이여서 GC가 수행되지 않는다.


let a = {};
let b = {};
a.test = b;
b.test2 = a;

마크 스위프

  1. 객체가 필요한지 결정하기 위해 해당 객체에 접근할 수 있는지 판단
  2. 모든 root(전역객체)와 그 자식 객체를 검사해서 활성화 여부를 표시(활성상태면 gc대상 아님)
  3. 활성 상태가 아닌 값들은 메모리를 os에 번환

전역변수 user는 {name : "홍길동"}객체를 참조한다. 즉, global(root)을 통해서 자식 객체로 {name : "홍길동"}에 접근할 수 있다.


let user = {
 name : "홍길동"
}

user를 null로 처리하면 root에서 접근할 수 없다. 따라서 GC수거 대상이 된다.

user = null;

참조 카운팅에서 발생하는 순환참조 문제가 발생하지 않는다. family의 father,mather가 서로를 참조하고 있지만 family를 null처리하면 family를 통해서 father,mother에 접근할 수 없기 때문에 GC 대상이 된다.

function marry(man, woman) {
  woman.husband = man;
  man.wife = woman;

  return {
    father: man,
    mother: woman
  }
}

let family = marry({
  name: "John"
}, {
  name: "Ann"
});

family = null;

자바스크립트 메모리 누수

전역 변수

  • 선언되지 않은 변수가 참조되면 전역 객체에 변수를 생성한다.
  • 전역객체에 변수가 들어가면서 메모리 누수 발생
  • use strict 키워드로 메모리 누수 막을 수 있다.
function test() {
    a = "memory leak";
}
function test() {

    window.a = "memory leak";
}

클로져

  • 개발자가 의도적으로 클로저를 사용한 경우에는 메모리 누수가 발생한게 아니지만, 의도치 않게 클로져가 만들어지고 메모리 해제를 하지 않으면 메모리 누수가 발생한다.

정리

  • 가비지 컬렉션은 자동으로 실행되서, 강제로 실행하거나 막ㅇ르 수 없다.
  • 객체는 접근가능한 동안에는 메모리에 계속 유지