객체 풀링

가능한 경우 객체 풀링을 사용합니다.

또 다른 중요한 최적화 방법은 시간 경과에 따라 객체를 다시 사용하는 것과 관련된 객체 풀링 기술입니다. 응용 프로그램 초기화 동안 정의된 수의 객체를 만들어 Array 또는 Vector 객체 등의 풀 내부에 저장합니다. 객체 사용을 마치면 객체가 CPU 리소스를 사용하지 않도록 객체를 비활성화하고 상호 참조를 모두 제거합니다. 그러나 참조를 null 로 설정하지는 않습니다. null로 설정하면 객체가 가비지 수집 대상이 될 수 있습니다. 풀에 다시 넣으면 새 객체가 필요할 때 가져올 수 있습니다.

객체를 다시 사용하면 리소스를 많이 사용하는 객체 인스턴스화 작업을 수행해야 할 필요성이 줄어듭니다. 또한 응용 프로그램의 속도를 저하시킬 수 있는 가비지 수집기 실행 빈도도 줄일 수 있습니다. 다음 코드는 객체 풀링 기술을 보여 줍니다.

package 
{ 
    import flash.display.Sprite; 
     
    public final class SpritePool 
    { 
        private static var MAX_VALUE:uint; 
        private static var GROWTH_VALUE:uint; 
        private static var counter:uint; 
        private static var pool:Vector.<Sprite>; 
        private static var currentSprite:Sprite; 
  
        public static function initialize( maxPoolSize:uint, growthValue:uint ):void 
        { 
            MAX_VALUE = maxPoolSize; 
            GROWTH_VALUE = growthValue; 
            counter = maxPoolSize; 
             
            var i:uint = maxPoolSize; 
             
            pool = new Vector.<Sprite>(MAX_VALUE); 
            while( --i > -1 ) 
                pool[i] = new Sprite(); 
        } 
         
        public static function getSprite():Sprite 
        { 
            if ( counter > 0 ) 
                return currentSprite = pool[--counter]; 
                 
            var i:uint = GROWTH_VALUE; 
            while( --i > -1 ) 
                    pool.unshift ( new Sprite() ); 
            counter = GROWTH_VALUE; 
            return getSprite(); 
             
        } 
  
        public static function disposeSprite(disposedSprite:Sprite):void 
        { 
            pool[counter++] = disposedSprite; 
        } 
    } 
}

SpritePool 클래스는 응용 프로그램 초기화 시 새로운 객체의 풀을 만듭니다. getSprite() 메서드는 이러한 객체의 인스턴스를 반환하고 disposeSprite() 메서드는 이들을 해제합니다. 이 코드에서는 풀이 완전히 사용되었을 때 풀을 확장할 수 있습니다. 또한 풀이 소모되었을 때 새 객체를 할당하지 않는 고정된 크기의 풀을 만들 수도 있습니다. 가능하면 루프에서 새 객체를 만들지 않는 것이 좋습니다. 자세한 내용은 메모리 해제 를 참조하십시오. 다음 코드에서는 SpritePool 클래스를 사용하여 새 인스턴스를 가져옵니다.

const MAX_SPRITES:uint = 100; 
const GROWTH_VALUE:uint = MAX_SPRITES >> 1; 
const MAX_NUM:uint = 10; 
  
SpritePool.initialize ( MAX_SPRITES,  GROWTH_VALUE ); 
  
var currentSprite:Sprite; 
var container:Sprite = SpritePool.getSprite(); 
  
addChild ( container ); 
  
for ( var i:int = 0; i< MAX_NUM; i++ ) 
{ 
    for ( var j:int = 0; j< MAX_NUM; j++ ) 
    { 
        currentSprite = SpritePool.getSprite(); 
        currentSprite.graphics.beginFill ( 0x990000 ); 
        currentSprite.graphics.drawCircle ( 10, 10, 10 ); 
        currentSprite.x = j * (currentSprite.width + 5); 
        currentSprite.y = i * (currentSprite.width + 5); 
        container.addChild ( currentSprite ); 
    } 
}

다음 코드에서는 마우스 클릭 시 표시 목록에서 모든 표시 객체를 제거하고 나중에 다른 작업에서 이들 객체를 다시 사용합니다.

stage.addEventListener ( MouseEvent.CLICK, removeDots ); 
  
function removeDots ( e:MouseEvent ):void 
{ 
    while (container.numChildren > 0 ) 
        SpritePool.disposeSprite (container.removeChildAt(0) as Sprite ); 
}
참고: 풀 벡터는 항상 Sprite 객체를 참조합니다. 객체를 메모리에서 완전히 제거하려면 남아 있는 모든 참조를 제거하는 SpritePool 클래스의 dispose() 메서드가 필요합니다.