Unexpected Memory Leak (無名関数の濫用はメモリリークの温床!)
----------------------------------------------------------------------------
* An unexpected memory leak can be caused by the abuse of function closure!
* ----------------------------------------------------------------------------
* 最近知った知識を他人にやたら得意げにひけらかしたがるは人の常。
* 理解していたようであまり意識してなかった・・・という方も多いのではないかと勝手に推測。
*
* [see also]
* アクティベーションオブジェクトによるメモリリーク
* http://www.imajuk.com/blog/archives/2008/04/post_3.html
* ----------------------------------------------------------------------------
* [適当な要約]
* ・無名関数は、望む望まざる・必要不必要に関わらず、定義されたスコープ内の"全ての"ローカル変数を保存する。
* ・無名関数が破棄されるまで、全く不用なローカル変数であっても破棄されず、メモリを無駄に占有し続ける。
*
* [教訓]
* ・別にメソッドを定義するのが面倒だという理由だけで、無名関数を書くのはなるべく控えよう。
* ・クロージャを使いたい時は、クロージャを生成して返すメソッドを別に用意しよう。
* ----------------------------------------------------------------------------
* [補足]
* 実行する環境等によって、使用中のメモリが表示に正しく反映されない場合があります。
* ( http://www.justsuppose.com/some-systemgc-and-systemtotalmemory-tips/ )
* 開始時のメモリ使用量が30MB超~になるような環境でお試しください。
/**
* Copyright o8que ( http://wonderfl.net/user/o8que )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/rzup
*/
/* ----------------------------------------------------------------------------
* An unexpected memory leak can be caused by the abuse of function closure!
* ----------------------------------------------------------------------------
* 最近知った知識を他人にやたら得意げにひけらかしたがるは人の常。
* 理解していたようであまり意識してなかった・・・という方も多いのではないかと勝手に推測。
*
* [see also]
* アクティベーションオブジェクトによるメモリリーク
* http://www.imajuk.com/blog/archives/2008/04/post_3.html
* ----------------------------------------------------------------------------
* [適当な要約]
* ・無名関数は、望む望まざる・必要不必要に関わらず、定義されたスコープ内の"全ての"ローカル変数を保存する。
* ・無名関数が破棄されるまで、全く不用なローカル変数であっても破棄されず、メモリを無駄に占有し続ける。
*
* [教訓]
* ・別にメソッドを定義するのが面倒だという理由だけで、無名関数を書くのはなるべく控えよう。
* ・クロージャを使いたい時は、クロージャを生成して返すメソッドを別に用意しよう。
* ----------------------------------------------------------------------------
* [補足]
* 実行する環境等によって、使用中のメモリが表示に正しく反映されない場合があります。
* ( http://www.justsuppose.com/some-systemgc-and-systemtotalmemory-tips/ )
* 開始時のメモリ使用量が30MB超~になるような環境でお試しください。
*/
package {
import com.bit101.components.*;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.system.System;
import net.hires.debug.Stats;
public class Main extends Sprite {
public function Main() {
addChild(new Stats());
test();
// debugger version only
//addEventListener(Event.ENTER_FRAME, function(e:Event):void { System.gc(); } );
}
private function test():void {
// 何か巨大なオブジェクトを生成し、"一時的に"ローカル変数に格納したつもりになっている。
var size:int = 2880; //4096;
var someLargeObject:BitmapData = new BitmapData(size, size, true, 0x00ffffff);
// 同メソッド内で無名関数を定義する。
new PushButton(this, 80, 25, "removeEventListener", function(e:MouseEvent):void {
new Label(e.currentTarget.parent, 80, 45, "wait for garbage collection...");
e.currentTarget.removeEventListener(MouseEvent.CLICK, arguments.callee);
});
// このtestメソッドを抜けたとき、巨大なオブジェクトがガベージコレクションの対象になると思い込んでいませんか?
}
}
}