ECMAScript 2015(ES6) #1 추가된 기본 문법
Javascript #3 가비지 콜렉션
2018-02-01
Explanation
글을 시작하기에 앞서, 이 글은 아주 간단하고 가볍게 가비지 콜렉션에 대해 정리한 글 입니다. 보다 자세한 정보는 아래의 참고 링크를 확인하시면 좋을 것 같습니다.
1. developer.mozilla.org
2. theeye.pe.kr
자바스크립트를 포함한 여러 고급 언어들은 개발자가 직접 메모리를 할당해주거나 해제하지 않고 언어의 인터프리터가 그 역할을 대신 해주며, 변수에 값을 담거나 함수나 메소드를 통해서 메모리가 할당되고 사용됩니다. 그리고 할당된 메모리 영역 중에서 필요없게 된 영역을 해제해주는 기능을 하는데 이 부분을 가비지 콜렉션이라고 합니다.
가장 무난한 알고리즘 방식이라고 하며, 인터넷 익스플로러 6, 7 에서 수행된다고 하는 것으로 보아 조금 이전 세대의 가비지 콜렉션 알고리즘으로 생각됩니다. 간단하게 mozilla.org에서 설명한 글을 옮기면 ‘어떤 다른 오브젝트도 참조하지 않는 오브젝트’ 라고 정의합니다.
1 2 3 4 5 6 |
let a = { key : 'value'}; // 메모리에 { key : 'value'} 라는 오브젝트가 할당되고 변수 a는 그 오브젝트를 참조합니다. a = null; // 변수 a에 다른 값을 할당하였습니다. // 이제 { key : 'value'} 라는 오브젝트는 어느곳에서도 참조되지 않아 가비지 콜렉션이 수행됩니다. |
하지만 아래와 같이 두개의 오브젝트가 서로를 참조하면, 두 오브젝트는 필요없게 되었지만 가비지 콜렉션을 수행하지 않습니다.
1 2 3 4 5 6 7 8 9 10 |
function a() { let b = {}; let c = {}; b.b = c; // b는 c를 참조하고 c.c = b; // c는 b를 참조합니다. return true; } a(); //가비지 콜렉션이 수행되지 않습니다. |
최신의 브라우저들은 표시하고-쓸기 알고리즘을 사용하고 있다고 합니다, 역시 간단하게 mozilla.org에서 설명한 글을 옮기면 ‘닿을 수 없는 오브젝트’ 라고 정의합니다. (이후 다양한 엔진에서 개선된 알고리즘이 적용되고 있지만 여전히 필요하지 않은 오브젝트를 ‘닿을 수 없는 오브젝트’라고 정의한다고 합니다.)
전역 변수들을 시작으로 그들이 참조하는 오브젝트들을 따라가 마크를 남기고 그렇게 닿을 수 없게 된 오브젝트들은 가비지 콜렉션이 수행되어 메모리 영역에서 해제됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
let a = { b: 'b' }; let b = { c: 'c' }; let c = { d: 'd' }; b.d = c; // { d: 'd' } 오브젝트는 b 오브젝트의 속성으로 참조됩니다. a.c = b; // console.log(a); // { // b: 'b', // c: { c: 'c', // d: { d: 'd' } // } // } c = null; b = null; // 이제 전역에서 오브젝트를 참조하는 변수는 a 뿐입니다. a.c.d = null; // console.log(a); // { // b: 'b', // c: { c: 'c', // d: null // } // } |
위 이야기 처럼 전역의 변수 a가 참조하는 오브젝트들을 따라가다보면 더 이상 { d: ‘d’ } 라는 오브젝트에 닿을 수 없기에 가비지 콜렉션에 의해 메모리 영역이 해제됩니다.
위 예제 코드는 참조-세기(Reference-counting) 알고리즘으로도 가비지 콜렉션이 수행되겠지만, 코드만으로 최대한 간단히 1차원적으로 작성하려다보니.. 좀 이상한 코드가 되었습니다..