2. 참조값과 가비지컬렉팅

참조값

참조값의 특징은 아래와 같다.

  1. 복제되지 않고

  2. 원본은 하나만 유지된 상태로

  3. 주소만 공유되는 것

자바스크립트에서는 이전에 언급한 기본값을 제외하면 모든 것이 참조값이다.

참조값의 주요한 문제 중 하나는 가비지컬렉팅이다.

var a = b = {key: 'test'};

위의 코드는 동일한 객체에 대한 참조를 두 변수가 갖고 있다. 이 중 한쪽의 참조를 인위적으로 풀어보자.

a = null;

하지만 여전히 남은 b가 참조를 쥐고 있다. b 도 해지해보자. 하지만 이번엔 null 을 넣는게 아닌 다른 참조를 넣어 해지해보자. (문제는 없음 그냥 이렇게 하는거임)

var a = b = {key:'test'};
 
a = null;
b = {};

이렇게 되면 {key: "test"} 에 대한 연결고리가 모두 끊어져서 가비지컬렉션이 이를 해제한다.

위와 같은 경우는 매우 간단하기 때문에 우리가 직접 모든 연결고리를 끊어서 메모리 관련 문제가 생기지는 않았지만, 프로그램이 복잡해진다면 이런 하나하나 별거 하닌 것들을 잘 못해서 가비지 컬렉팅 되지 못한 객체들이 메모리를 잠식해서 브라우저가 느려지는 원인이 된다.

가비지 컬렉팅

자바스크립트의 메모리 기본 전략은 가비지컬렉팅이다. 가비지 컬렉팅은 해당 객체를 참조하는 변수가 없으면 이를 메모리에서 제거하는 것. 반대로 가비지컬렉팅을 사용한다는 것은 자바스크립트에게 객체를 생성하거나 할당할 때의 메모리를 맡긴다는 뜻이다.

문제는 바로 여기서 일어난다. 개발자가 자유롭게 객체 생성과 해지를 반복하면 메모리 단편화 현상이 생긴다. 단편화 현상이란 아래와 같은 문제다.

  1. 전체 가용 메모리 공간이 10 메가라고 할 때

  2. 메모리 영역의 가운데 쯤에 1메가 짜리 객체를 할당하면,

  3. 그 객체의 메모리를 기준으로 앞쪽에 4메가, 뒤쪽에 5메가의 공간으로 분리된다.

  4. 따라서 남은 메모리가 9메가지만 5메가 이상의 객체를 할당할 방법은 사라졌다.

이 문제를 해결하기 위해서는 메모리를 재배치해야한다. 문제는 메모리 어디에 객체를 할당할지는 개발자가 정하는게 아니라 자바스크립트가 정한다는 사실이다. 따라서 메모리 재배치를 통해 단편화를 해결할 수는 없다. 그렇다면 어떻게 해야할까....

가장 많이 사용되는 방법은 인생에서 가장 중요한 것부터 해라! 이다. 예를 들면 상자에 작은 돌과 큰 돌을 어떻게 넣으면 가장 효과적일까라는 문제의 답이, 일단 큰 것부터 넣고 작은것은 큰 것 사이로 넣으면 된다! 라는 것처럼 메모리 관리에서도 프로그램이 사용할 객체 중 가장 덩치가 큰 객체를 미리 할당해버리는 것이다.

단편화 문제와 더불어 또 한가지 문제는 new 의 비요이 비싸고 null 을 할당하여 가비지컬렉팅 대상이 늘어나는 것도 비용이 상당하다는 것. New 를 줄이는 방법은 객체를 재사용 하는 것이다. 재사용한다는 것은 객체의 속성을 초기화하고 사용하는 것이라는 의미다. 그리고 이게 속도측면에서는 훨씬 빠르다.

Last updated