Understanding garbage collection in Flash Player 9

원문 싸이트

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들은 서로 그들의 자식과부모 양방향으로 연결되어그들을 영원히 해결할수 없을 것 같았다.

다행히도플래쉬 플레이어부터 mark  sweep 으로 불리는 새로운 가비지콜랙션 기술이 추가되었다.

 

Mark sweeping

AS3.0(그리고 플래쉬 플레이어 8)에 의해서 죽어있는객체들을 찾아내기 위한 가비지 콜랙터에게 고용된 두번째 전략은 바로 MarkSweep이다.(이사람 말하는게 참 잼있네요-_-;)

플래쉬 플레이어는 어플리케이션의 루트객체(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이면 지워지는 것을 확인해 보세요

잼있네요 이거 ㅡㅅㅡ; )

(요것도 그림이 안되네요; 클릭!)

 

앞으로의 향방

가비지 콜렉션을 이해한다는 것은 당신의플래쉬(플렉스)프로젝트가 사용자의 컴퓨터에 최소한의 부담을주며 동작하는 활용적인 코드를 만드는데 가장 중요한 첫걸음이 될 것이다.