원문 싸이트
http://www.adobe.com/devnet/flashplayer/articles/garbage_collection.html
번역 by 노리노리.
… 인사글 생략…
당신의 코드가 AS3.0에서 얼마나 능률적으로 작동하는지 이해하려면, 먼저 가비지 콜렉터가 플래쉬 플레이어 9에서 어떻게 동작하는지에대한 이해가 필요하다.
플래쉬는 사용되지않는 객체를 찾고 그것들을 지우는 두개의 프로세스를 가지고있다.
여기서는 이 두가지에 대한 기술과 그것들이 당신의 코드에 어떻게 적용되는지에 대해 알아보겠다.
이 문서의 마지막 부분에서 플래쉬 플레이어9의 가비지 콜랙터가 어떻게동작하는지 눈으로 확인할 수 있는 시뮬레이션을 볼수 있을 것이다.
About the garbage collector
가비지 콜렉터란, 어플리케이션에서 더 이상 사용되지 않는 객체들이메모리를 사용하는것에 대해 처리를 맡는 책임을 지닌 숨겨진 숨은 프로세스(behind-the-scenes)이다.
이걸 이해하기 위해서는, non-primitive type (Boolean,String, Number, unit, int외의 아무것)들과 작업할 때, 당신은 항상 객체들을 참조하고있다는 점(객체 그 자체가 아니다)을
인식하는 것이 매우 중요하다.
여기 이해를 도와줄 코드를 보자:
// create a new object, and put a referenceto it in a:
var a:Object = {foo:"bar"}
// copy the reference to the object into b:
var b:Object = a;
// delete the reference to the object in a:
delete(a);
// check to see that the object is stillreferenced by b:
trace(b.foo); // traces "bar", sothe object still exists.
만약 내가 코드에 delete(b)를 추가한다면, 죽어있는 참조 그대로 객체는 남게될 것이며,
가비지콜랙션에게 수집될것이다. AS3.0 가비지콜렉터는 죽은참조를가진 객체들의 위치를 찾기위해 두가지 방법을 사용한다: reference counting과 mark sweeping이 그것이다.
Reference Counting
레퍼런스 카운팅은 살아있는 객체들의 트렉을유지하기 위한 가장 간단한 방법중 하나이며,
ActionScript1.0때부터 사용되어 왔다.객체를 참조하면, 그것의 참조수가 증가된다.
참조를 지우면, 그것의 참조수는 감소한다. 만약 객체의 참조수가 0이 되면, 그 객체는
가비지 콜렉터에의해 지워지도록 마크(mark)된다.
예제:
vara:Object = {foo:"bar"}
// theobject now has a reference count of 1 (a)
varb:Object = a;
// now ithas a reference count of 2 (a & b)
delete(a);
// backto 1 (b)
delete(b);
// thereference count down is now 0
// theobject can now be deallocated by the garbage collector
레퍼런스 카운팅은 간단하다. CPU에게 부담이 안되며, 대부분의 상황에서 잘 동작한다.
단, 불행하게시리, 가비지콜렉션의 레퍼런스 카운터 방식은 언제 그 참조수를 카운트하러
올지가 불확실하다는 것. 레퍼런스의 수를 계산하는 시기는 바로 객체들이 서로를 참조할 때이다(직접, 혹은 다른객체를 통한 간접이든).위의 방법으로는 객체들을 사용하는 어플리케이션이 더이상 동작하지 않는다 하더라도, 객체의 참조수가 0보다 크면, 가비지 콜렉터는 그들을 절대 제거하지 않는다.
아래 코드를 보자.
vara:Object = {}
// createa second object, and reference the first object:
varb:Object = {foo:a};
// makethe first object reference the second as well:
a.foo =b;
// deleteboth active application references:
delete(a);
delete(b);
위의 코드를 보면, 두개의 참조들은 모두 삭제되었다. 난 더 이상 저 두객체들을 참조하거나제어할 길이 전혀 없다. 하지만, 저 두 객체들의 참조수는여전히 1이다. 왜냐면 그들은
서로 참조를 하고있기 때문이다. 이런 상황은 훨씬더 복잡해질수 있으며(c라는 객체를 위의 두 객체(a,b)와 삼각형으로 맞물려놓는다던지..), 그걸 해결하는게 더 어려워질수 있다.
플래쉬 플레이어6과 7에서는 XML 객체들의레퍼런스를 계산하는것에 이슈가된적이 있다.
- 각 XML node들은 서로 그들의 자식과부모 양방향으로 연결되어, 그들을 영원히 해결할수 없을 것 같았다.
다행히도, 플래쉬 플레이어8 부터 mark 와 sweep 으로 불리는 새로운 가비지콜랙션 기술이 추가되었다.
Mark sweeping
AS3.0(그리고 플래쉬 플레이어 8)에 의해서 죽어있는객체들을 찾아내기 위한 가비지 콜랙터에게 고용된 두번째 전략은 바로 Mark와Sweep이다.(이사람 말하는게 참 잼있네요-_-;)
플래쉬 플레이어는 어플리케이션의 루트객체(root object, AS3.0에선 편리하게 ‘root’라는 이름으로사용)에서 시작해 모든 연결된 객체들을 타고 내려가면서 찾은 것들을marking 한다.
그다음,플래쉬 플레이어는 마크된 객체들을 되풀이하며 돈다. 이 동작은 재귀적으로 어플리케이션의모든 객체 트리를 전부 지나갈 때까지 계속된다. 이 작업이 끝날 때,플래쉬 플레이어는 메모리의 마크되지 않은 객체들은 더 이상 살아있는 참조를 가지고 있지않으며 안전하게 지워도 된다고 안심하게 된다.
그림1이어떻게 동작하는지 보여준다. 녹색 화살표들은 플래쉬 플래이어에 의해 마킹되어진 경료이며, 녹색 객체들은 마크된것들, 하얀색은 청소될 객체들이다.
Mark와 Sweep은 매우 용의주도하다. 하지만, 플래쉬 플레이어가 모든 객체 구조를 돌아다녀야 하기 때문에, CPU에 부담을 줄 수 있는 작업이다. 플래쉬 플레이어9는 서로 영향을 주는(interactive) mark와 sweep을 실행하고(프로세스는 한번에 처리하는 대신 프레임수 초과를일으킨다), 이 작업을 가끔씩 실행시키는 것으로 CPU의부담을 줄였다.
Deferred garbage collector andindeterminacy
(연기된 가비지 콜렉터와 불확성)
플레쉬 플레이어9에서, 가비지 콜렉터의 연산들은 연기된다. 이건 아주아주 이해하는데
아주아주 중요한 점이다. 모든 살아있는 레퍼런스들이 지워졌을 때도 당신의 객체들은 그 즉시 삭제되지 않을것이다. 대신, 그것들은 미래(개발자의관점에서)의 어느 한순간 삭제될 것이다. 가비지 콜렉터는다른것들 보다도 RAM의 할당과 메모리 스택의 크기를 보는 발견적 방법들의 집합을 사용한다.
개발자로써, 당신은 비록 사용하지 않는 객체들이 지워질 거라는 것은 알지만, 그게언제인지 알아낼 방법이 전혀 없다는 것을 인정해야만 한다. 또한 가비지 콜렉터가 그들을 삭제하기 전까지죽어있는 객체들은 코드들을 무한히 실행하고 있다는 사실, 소리는 계속 난다것, 로딩은 계속 일어나고 있다는 것, 그외 여러 이벤트들은 계속 불타오르고있다는 것 등등, 이러한 사실 또한 명심해야 한다. (말하는게진짜;;;유머감각투철한.. -_-;;)
플래쉬 플레이어의 가비지 콜렉터가 당신의객체들을 지우는 타이밍을 조절할 방법이 없다는 것을 절대적으로 기억하라. 개발자로써, 당신은 당신의 게임이나 어플리케이션 안에
가능한 한 많이 당신의 객체들을 작업이끝날때까지 집어넣고 싶을 것이다. (-_-;;)
이 작업을 잘 메니지할 전략은 나의 다른논제인, Resourcemanagement strategies in Flash Player 9. 에서 다루어 질 것이다.
아래의 가비지 콜렉션 시뮬레이션에서 전체메모리가 송곳니패턴을 이루고있음을 주목하라.
(그림을 Ctrl+클릭). 콜렉터가 sweep을 실행할 때 계곡이 발생한다.
링크창을 띄우고 스페이스바로 정지와 재생을눌러가면서 메모리 사용량이 위아래로 움직이는 모습을 잘 살펴보라.
아래의 시물레이션에서(마찬가지로 컨트롤+클릭), 객체들을드래그아웃하고 그 객체들을 연결시킨다. (마음데로 루트로부터 트리를 만들어 마크를 클릭해서 마크되는걸보고
연결선을 지워가면서 마크되지 않은 것이 sweep을 눌렀을 때 빨갏게 되고 collect를 눌렀을 때 지워지는모습을 보라. 선이 연결되지 않았어도 레퍼런스수가 0보다크면 지워지지
않는 것과 선이 연결되어있어도 레퍼런스수가 0이면 지워지는 것을 확인해 보세요
잼있네요 이거 ㅡㅅㅡ; )
앞으로의 향방
가비지 콜렉션을 이해한다는 것은 당신의플래쉬(플렉스)프로젝트가 사용자의 컴퓨터에 최소한의 부담을주며 동작하는 활용적인 코드를 만드는데 가장 중요한 첫걸음이 될 것이다.