In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: Castさんはなぜ…

※ 未解決に差し戻しました
forkして頂いたコードでご指摘を受けた通りでした。
浅い知識でレスポンスしてしまい、申し訳ありません。

私もprogressionのソースをcheckoutしてみました。
関連クラスを眺めてみましたが、これを綺麗にfixするのは骨が折れそうなので
progressionの作者さんにお任せしたいと思います。

jp.nium.core.collections.ExDisplayCollection._instances と、
jp.nium.display.ChildIndexer._indexers の二つのDictionaryの参照を
明示的に外すと、リークがかなり軽減される様です。

ExDisplayCollection._instances の方は弱参照Dictionaryですが
キーではなく値としてCastSpriteの参照を保持しているので、
解放したい場合は何らかの方法で参照を外す必要があるかと思います。
(あるいは、有効なDisplayObjectContainerにaddChildされるまで
_instancesに参照させない様にする等)

ChildIndexer._instances も弱参照Dictionaryで、
こちらはキーとしてCastSpriteの参照を保持していますが
_instancesがstaticメンバである為か、GCの対象にならない様です。

また、cast.parallelMode = false; で発生する例外に関しては、
実体がSerialListなのにPararellListに無理やりキャストした上でtoSerialList()している為に発生する様です。
_commandListの型チェックを入れれば解決するかと思います。
ex.)
if ( _parallelMode = value ) {
if( _commandList is SerialList ){
_commandList = SerialList( _commandList ).toParallelList();
}
} else {
if( _commandList is ParallelList){
_commandList = ParallelList( _commandList ).toSerialList(
Get Adobe Flash player
by hacker_y48qdmdh 02 May 2009
/*
※ 未解決に差し戻しました
   forkして頂いたコードでご指摘を受けた通りでした。
   浅い知識でレスポンスしてしまい、申し訳ありません。
   
私もprogressionのソースをcheckoutしてみました。
関連クラスを眺めてみましたが、これを綺麗にfixするのは骨が折れそうなので
progressionの作者さんにお任せしたいと思います。

jp.nium.core.collections.ExDisplayCollection._instances と、
jp.nium.display.ChildIndexer._indexers の二つのDictionaryの参照を
明示的に外すと、リークがかなり軽減される様です。

ExDisplayCollection._instances の方は弱参照Dictionaryですが
キーではなく値としてCastSpriteの参照を保持しているので、
解放したい場合は何らかの方法で参照を外す必要があるかと思います。
(あるいは、有効なDisplayObjectContainerにaddChildされるまで
 _instancesに参照させない様にする等)

ChildIndexer._instances も弱参照Dictionaryで、
こちらはキーとしてCastSpriteの参照を保持していますが
_instancesがstaticメンバである為か、GCの対象にならない様です。

また、cast.parallelMode = false; で発生する例外に関しては、
実体がSerialListなのにPararellListに無理やりキャストした上でtoSerialList()している為に発生する様です。
_commandListの型チェックを入れれば解決するかと思います。
ex.)
if ( _parallelMode = value ) {
    if( _commandList is SerialList ){
         _commandList = SerialList( _commandList ).toParallelList();
    }
} else {
    if( _commandList is ParallelList){
        _commandList = ParallelList( _commandList ).toSerialList();
    }
}
*/

// 参考URL:
// http://forum.progression.jp/index.php?topic=35.0
// http://forum.progression.jp/index.php?topic=80.0

// forked from sph62's Castさんはなぜ…
/**
 * Castさんはメモリの解放をしてくれないのでしょうか?
 * 何か間違えてる??
 *
 * @use SWFProfiler
 *
 * ...
 * @author sph62
 */
package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.text.TextField;
    import flash.system.System;
    import flash.utils.setTimeout;
    import flash.utils.setInterval;
    import jp.progression.casts.CastSprite;
    import com.flashdynamix.utils.SWFProfiler;
    
    public class FlashTest extends Sprite {
        
        private var tf:TextField
        
        public function FlashTest() {
            // write as3 code here..
           if (stage) init();
           else addEventListener(Event.ADDED_TO_STAGE, init);
           
        }
        
        private function init(e:Event = null):void {
           removeEventListener(Event.ADDED_TO_STAGE, init);
           SWFProfiler.init(this);
           
           tf = new TextField();
           tf.multiline = true;
           tf.width = stage.stageWidth;
           tf.height = stage.stageHeight;
           tf.text = "1秒後にSpriteをテストします。\ngcして、5秒待ってCastSpriteをテストします。\n"
                     
           addChild(tf)
           
           setTimeout(testSprite,1000);
           setTimeout(testCast,6000);
           setInterval(memTrace,10000);
       }
       
       private function testSprite():void{
           tf.appendText("Spriteを addChild → removeChild → null を 10000回\n");
           tf.appendText("[Memory] "+(System.totalMemory/1000000).toString()+"MB\n")          
           
           for(var i:int = 0;i<10000;i++){
                var sp:Sprite = new Sprite();
                addChild(sp);
                removeChild(sp);
                sp = null;
           }
           tf.appendText("end & gc\n");
           SWFProfiler.gc();
           tf.appendText("[Memory] "+(System.totalMemory/1000000).toString()+"MB\n");
       }
       
       private function testCast():void{
           tf.appendText("CastSpriteを addChild → removeChild → null を 1000回\n");
           tf.appendText("[Memory] "+(System.totalMemory/1000000).toString()+"MB\n")          
           
           for(var i:int = 0;i<1000;i++){
                var cast:CastSprite = new CastSprite();
                // cast.parallelMode = false; // これではダメ
 
                addChild(cast);
                removeChild(cast);
                                
                cast = null;
           }
           tf.appendText("end & gc\n");
           SWFProfiler.gc();
           tf.appendText("[Memory] "+(System.totalMemory/1000000).toString()+"MB\n")          
           
       }
        
       private function memTrace():void{
           tf.appendText("[Memory] "+(System.totalMemory/1000000).toString()+"MB\n")          
       }
        
    }
}