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

LocalConnectionで強制的にGCを起こす

クリックでGCを起こすテスト
Get Adobe Flash player
by su10 19 Oct 2014
    Embed
/**
 * Copyright su10 ( http://wonderfl.net/user/su10 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/b2zq
 */

// forked from su10's 関数クロージャでメモリリークが発生する例
package {
    import flash.display.Stage;
    import flash.events.MouseEvent;
    import flash.text.TextFormat;
    import flash.text.TextField;
    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.events.TimerEvent;
    import flash.utils.Timer;
    import flash.display.Sprite;
    import flash.system.System;
    import flash.net.LocalConnection;

    public class ClosureMemoryLeakTest extends Sprite {
        private var traceTextField:TextField;
        private var timer:Timer;
        private var funcVector:Vector.<Function>;
                
        public function ClosureMemoryLeakTest() {
            traceTextField = new TextField();
            var format:TextFormat = new TextFormat();
            format.size = 64;
            traceTextField.defaultTextFormat = format;
            traceTextField.background = true;
            traceTextField.backgroundColor = 0xFFFFFF;
            traceTextField.autoSize = 'left';
            traceTextField.text = '0KB';
            traceTextField.x = 10;
            traceTextField.y = 10;
            this.addChild(traceTextField);
            
            timer = new Timer(1000, 5);
            timer.addEventListener(TimerEvent.TIMER, onTimer);
            timer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
            timer.start();
            
            funcVector = new Vector.<Function>();
            
            this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
            this.addEventListener(MouseEvent.CLICK, onClick);
        }
        
        private function onTimer(e:TimerEvent):void {
            // 約1.8MBのBitmapData
            var bitmapData:BitmapData = new BitmapData(800, 600);
            
            funcVector.push(
              function():void {
                  // スコープチェンによりbitmapDataを使用しなくてもbitmapDataへの参照を持ち続ける
                  // Chromeの場合はなぜかメモリ消費していかない
              }
            );
        }
        
        private function onTimerComplete(e:TimerEvent):void {
            funcVector = new Vector.<Function>();
            timer.start();
        }
        
        private function onEnterFrame(e:Event):void {
            update();
        }
        
        private function onClick(e:MouseEvent):void {
            // GCを強制的に引き起こす
            try {
                (new LocalConnection).connect('gc');
                (new LocalConnection).connect('gc');
            } catch(e:Error) {}
            
            traceTextField.backgroundColor = 0xFF0000;
            
            e.updateAfterEvent();
        }
        
        private function update():void {
            traceTextField.backgroundColor = 0xFFFFFF;
            traceTextField.text = (System.totalMemoryNumber / 1024).toString() + 'KB';
        }
    }
}