Flex ActionScript 関連覚書などなど

メモリリークをデバッグ(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プロジェクトとかに混ぜてもらえるかなぁ・・・。

コメント

コメント(1) “[as3]メモリリークをデバッグ(2)”

  1. yossy:beinteractive

    > こんくらいでもsparkプロジェクトとかに混ぜてもらえるかなぁ・・・。
    大歓迎ですよ!!

コメントする