본문 바로가기

Actionscript3.0

AS3.0 에서의 메모리 관리

package{                

	import flash.display.MovieClip;		
	import flash.display.Sprite;		

	/**	 * @author kang	 */		

	public class ResourceTest extends Sprite {		

		public function ResourceTest() {						

			var mc : MovieClip = new MovieClip();                        

			addChild(mc);			

			mc.addEventListener(Event.ENTER_FRAME, onEnterframeHandler);		

		}	
		private function onEnterframeHandler(event : Event) : void {			

			trace("execute event");		

		}	

	}

}
위와 같은 코드가 있다고 하자. mc는 Event.ENTER_FRAME 이벤트를 가지고 있는 객체 이다. 하지만 어떠한 상황이 발생하여 mc를 메모리 해제를 할 경우가 발생 하였다. 많은 AS개발자들이 아래와 같은 코드를 입력하여 메모리를 해제 할 것이다. 


private function disposeMc(_mc:MovieClip):void{	
	if(_mc.parent != null)		
	_mc.parent.removeChild(_mc);		
	_mc = null;
}
mc 라는 객체의 모든 참조 값이 제거 되었으므로 mc는 Garbage collection의 수집대상이 될 것이다. 그리고 곧 메모리 상에서 사라질 것이다. 하지만 이 코드에는 문제가 있다. 이벤트를 등록했던 객체는 사라졌지만, 등록된 이벤트 자체는 사라지지 않았다. 그래서 output 창에는 execute event 메시지가 계속호출 될 것이다. 많은 Flash 개발자들이 잘못 알고 있는게 해당 객체를 제거 하면 그 객체에 등록 되어 있던 이벤트들도 제거 된다고 생각한다. 이는 아주 심각한 문제를 발생 시킬수 있는 원인을 제공한다. 컴퓨터가 느려 진다던지, 메모리 사용량 증가로 프로그램 자체나, 브라우져가 멈춰 버리는 일이 발생 할 수도 있다. 그러므로 객체를 메모리 상에서 제거 하기 전에 반드시 removeEventListener로 이벤트를 반드시 해제 해야 한다. addEventListener 의 파라미터로 약한참조를 해 주면 객체가 제거 되면 그 객체에 등록되어 있는 이벤트들도 제거 되지만 약한 참조로 했을때 불편한 점이 많기 때문에 기본값은 강한참조로 되어 있다. 
addEventListener()메서드

public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void

useWeakReference는 false 값이 기본으로 강한 참조이다. 하지만 이 파라미터를 true로 넘겨 주면 약한 참조가 된다. 위에서 언급했듯이 약한 참조로 등록된 이벤트들은 해당 객체가 제거 되었을때 같이 메모리에서 제거 된다.



이와 비슷한 경우가 MovieClip을 사용할때 발생할 수 있다. 예를 들어 다음과 같이 1~40frame까지 계속
 

루프를 도는 MovieClip이 있다고 하자. 이렇게 루프를 돌고 있는 도중 갑자기 이 무비 클립을 메모리 상에서 제거 하면 어떤 일이 발생 할까?? 결과는 위 ENTER_FRAME 이벤트에서와 같이 계속 루프를 도는 현상이 발생한다. 계속 루프를 돈다는 것은 그 만큼 CPU를 사용한다는 말이 되고, 메모리 낭비를 하고 있다는 말이 된다. 하지만, 이걸 인식 하지 못하고 그냥 MovieClip만 제거 하면 해당 무비 클립에 대한 모든 것들이 메모리 상에서 없어 진다고 잘 못 생각하고 있는것이다. 그러므로 위와 같이 MovieClip을 사용한 작업을 할때는 꼭 MovieClip을 stop() 해 준뒤에 메모리를 해제 해 줘야 한다. stop 해주지 않고 메모리를 해제 했다간, 모든 참조 값들이 사라 졌기 때문에 해당 타임라인을 멈출 수 있는 방법이 존재 하지 않는다. 

이러한 리소스 관리 문제는 위의 두가지 경우에만 국한된 것이 아니다. AS에서 제공하는 Sound 나 Loader를 이용한 이미지로드 및 SWF 로드 또는 Video 작업을 할때 모두 위와 같은 메모리 문제가 발생 할 수 있다. 이 사실을 항상 유념하고 Flash 작업을 해야 한다. 더 자세한 AS3에서의 메모리 관리 방법은 다음 링크를 통해 확인 하길 바란다. 




예제다운로드

아무리 여러 테스트가 있어도, 정답은 "상황에 따라 맞는 방법을 쓴다." 이네요.