メモリリークをデバッグ(1)の続き。
実際にInstanceWatcherクラスを使ってみます。
ソースのオリジナルは、l4lさんの記事から。
package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.system.System; import flash.text.TextField; import flash.utils.Dictionary; [SWF(width="400", height="300")] public class test extends Sprite { private var _tf:TextField = new TextField(); private var iw:InstanceWatcher = InstanceWatcher.instance; private var dic:Dictionary; public function test() { _tf.width = 400; _tf.height = 300; addChild(_tf); dic = new Dictionary(true); stage.addEventListener(MouseEvent.CLICK, createObject); stage.addEventListener(Event.ENTER_FRAME, watch); } private function createObject(event:MouseEvent):void { for (var i:int = 0; i < 10; i++) { var sp:Sprite = new ExtSprite(); // GCされない //dic[sp] = null; dic[sp.name] = sp; new ExtSprite(); // こっちはGCされる } //System.gc(); } private function watchDictionary(event:Event=null):void { _tf.text = iw.getWatchString(); } } } import flash.display.Sprite; class ExtSprite extends Sprite {}
ちょこっと書き換えてますが、追加したのはほぼ2行です。
private var iw:InstanceWatcher = InstanceWatcher.instance;
まずここでシングルトンインスタンスを生成しておきます。
インスタンスを生成しないとサンプリングが開始されないので、
ルートのクラスで、コンストラクタ前に初期化してあります。
で、iw.getWatchString();で解析結果をStringで受け取る、と。これだけ。
プログラム実行直後の表示は、
———-
[class Object]:8
[class String]:1
[class Function]:2
[class Event]:1
[class EventDispatcher]:1
[class Dictionary]:1
[class ApplicationDomain]:1
[class Class]:4
[class LoaderInfo]:1
———-
こんな感じ。
で、クリックするたびに[class ExtSprite]の数が増えていきます。
10分くらい待つと・・・見事半分がガベージコレクションに持っていかれて、[class ExtSprite]の数が半分に。
ちなみに、半分残ってしまうのは、この部分。
dic[sp.name] = sp;
リファレンスを読むと、
> オブジェクトキーに "弱" 参照を使用するように、~~
Dictinaryが弱参照をするのは、オブジェクトキー指定したオブジェクトに対してですね。
ん~、ややこしいな!Dictinary!
dic[sp] = null;
に書き換えてやれば[class ExtSprite]が全部ガベージコレクションされるようになります。
とりあえず、flash.sampler.*系のクラス&メソッドは、
Flash Player デバッガ版の Update 3 以降が必要という制約はあるものの、
シングルトンインスタンスの生成と、出力の最低限2行を既存のプログラムに書き加えてやれば、
プログラム全体のインスタンス存在状況を見れる(はず)ということで、どうでしょうか?
あとは、出力周りとか得られる情報の種類とかいろいろ直さないとかな・・・。
こんくらいでもsparkプロジェクトとかに混ぜてもらえるかなぁ・・・。
> こんくらいでもsparkプロジェクトとかに混ぜてもらえるかなぁ・・・。
大歓迎ですよ!!