forked from: forked from: 弱参照のaddEventListenerのテスト

by tepe
addEventListenerしててもみんなガベコレされてるみたい
♥0 | Line 114 | Modified 2014-06-27 09:42:01 | MIT License
play

ActionScript3 source code

/**
 * Copyright tepe ( http://wonderfl.net/user/tepe )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/cpDh
 */

// forked from tosik's forked from: 弱参照のaddEventListenerのテスト
// forked from kjkmr's 弱参照のaddEventListenerのテスト
// forked from kjkmr's ガベージコレクションの観察
/*
addEventListenerしててもみんなガベコレされてるみたい
*/
package {
    import flash.display.*;
    import flash.text.*;
    import flash.utils.*;
    import flash.events.*;
    import caurina.transitions.Tweener;
    import flash.system.System;
    public class GarbageCollectionTest extends Sprite {
        
            private var _text:TextField = new TextField();
            private var _timer:Timer = new Timer( 2000 );
            private var _dic:Dictionary = new Dictionary( true );    
            private var _dummySprite:Sprite;
                
        public function GarbageCollectionTest() {
            GCChecker.init( this );
            GCChecker.addEventListener( GCEvent.GC, _onGC );
            
            //
            _timer.addEventListener( TimerEvent.TIMER, _onTimer );
            _timer.start();
            
            //
            _text.wordWrap = true;
            _text.width = stage.stageWidth;
            _text.height = stage.stageHeight;
            _text.text = "■開始\n\n";

            addChild( _text );
            
            //ローカル変数で適当なfunction
            var dummyHandler1:Function = function():void { _text.appendText("."); };
            var dummyHandler2:Function = function():void { _text.appendText("."); };
            
            //様々な種類のSpriteをDictionaryのキーに登録
            var s:Sprite;
            s = new Sprite();
            
            s.addEventListener( Event.ENTER_FRAME, dummyHandler1 );
            _dic[s] = "1. 普通にローカル変数のfunctionをaddEventListenerしたSprite";
            _dic[dummyHandler1] = "1. ローカル変数のfunction1";
            
            s = new Sprite();
            s.addEventListener( Event.ENTER_FRAME, dummyHandler2, false, 0, true );
            _dic[s] = "2. 弱参照:trueでローカル変数のfunctionをaddEventListenerしたSprite";
            _dic[dummyHandler2] = "2. ローカル変数のfunction2(弱参照で登録)";
            
            s = new Sprite();
            s.addEventListener( Event.ENTER_FRAME, _dummyHandler );
            _dic[s] = "3. 普通にクラスメンバのfunctionをaddEventListenerしたSprite";
            
            s = new Sprite();
            s.addEventListener( Event.ENTER_FRAME, _dummyHandler, false, 0, true );
            _dic[s] = "4. 弱参照:trueでクラスメンバのfunctionをaddEventListenerしたSprite";
            
            s = new Sprite();
            _dic[s] = "5. addEventListenerしてないSprite";
            
            s = new Sprite();
            _dic[s] = "6. クラスメンバに参照を保持したSprite";
            _dummySprite = s;
            
            //_dicの中身を表示
            _dumpDic();
        }
        
        /*--------------------------------------------------
        ダミーのイベントハンドラ
        --------------------------------------------------*/
        private function _dummyHandler( i_event:Event ):void {
                _text.appendText(".");
                _text.scrollV = _text.maxScrollV;
            }
        
        /*--------------------------------------------------
        メモリを無駄遣いするfunction
        --------------------------------------------------*/
        private function _wasteMemory():void {
                //メモリをたくさんつかう。maxを100に設定すると毎回GCが走る
                var max:uint = 100;
                var b:BitmapData;
                for ( var i:uint; i<max; i++ ){
                    b = new BitmapData( stage.stageWidth, stage.stageHeight );
                    b.draw(this);
                }
        }
        
        /*--------------------------------------------------
        定期的にメモリを無駄遣いするためのTimerのハンドラ
        --------------------------------------------------*/
        private function _onTimer( i_event:TimerEvent ):void {
                _text.appendText( "\n■Timer\n");
                _wasteMemory();
                //System.gc();//System.gcはDebugPlayerのみで有効らしい
                _text.scrollV = _text.maxScrollV;
        }
        
        /*--------------------------------------------------
        Dictionaryの中身をdump
        --------------------------------------------------*/
        private function _dumpDic():void {
                _text.appendText( "【_dicの中身】\n" );
                for each ( var item:* in _dic ) {
                    _text.appendText( item+"\n" );
                }
        }
        
        /*--------------------------------------------------
        ガベージコレクション発生時のハンドラ
        --------------------------------------------------*/
        private function _onGC( i_event:GCEvent ):void {
                _text.appendText( "\n■Garbages where collected!\n\n" );
            _dumpDic();
            _text.scrollV = _text.maxScrollV;
        }
    }
}


import flash.utils.Dictionary;
import flash.display.Sprite;
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.display.DisplayObject;
 
class GCChecker {
    private static var _dummyDic:Dictionary = new Dictionary( true );
    private static var _dispatcher:EventDispatcher = new EventDispatcher();
    private static var _displayObject:DisplayObject;
    private static function _onEnterFrame( i_event:Event ):void {
        var cnt:uint = 0;
        var item:*;
        for each ( item in _dummyDic ) cnt++;
        if ( cnt ) return;
        dispatchEvent( new GCEvent( GCEvent.GC ) );
        _dummyDic[new Sprite()] = "dummy";
    }
            
    public static function init( i_displayObject:DisplayObject ):void {
        _displayObject = i_displayObject;
        _displayObject.addEventListener( Event.ENTER_FRAME, _onEnterFrame );
        _dummyDic[new Sprite()] = "dummy";
    }
    
    public static function addEventListener( i_type:String, i_handler:Function ):void {
        _dispatcher.addEventListener( i_type, i_handler );
    }
    
    public static function removeEventListener( i_type:String, i_handler:Function ):void {
        _dispatcher.removeEventListener( i_type, i_handler );
    }
            
    public static function dispatchEvent ( i_event:Event ):void {
        _dispatcher.dispatchEvent( i_event );
    }
}
    
class GCEvent extends Event {
    public static const GC:String = "gc";
    public function GCEvent( i_type:String, i_bubble:Boolean = false, i_cancelable:Boolean = false ) {
        super( i_type, i_bubble, i_cancelable );
    }
}