DisplayObjectの配列参照とメモリ

2010.03.22  Category:ActionScript3.0

あるデバッグ中に、なんかメモリが残り続けました。
結局、犯人が配列だったというお話です。

使用済みのインスタンスをガベージコレクションの対象にするために、僕は、以下の項目を実行します。
・イベントを外す(removeEventListenerを実行)
・変数の参照を外す(null代入)
・Bitmapインスタンスの場合、bitmapDataプロパティが存在していたら、開放する(dispose実行)

インスタンスを生成し、使い終わったら上記の項目(イベントは登録していないので、「イベントを外す」は実行していません。)を実行したのが、以下のコード。

package
{
	import flash.display.*;
	import flash.events.Event;
	public class Hoge extends Sprite
	{
		private var _arr:Array = [];
		public function Hoge()
		{
			addEventListener(Event.ENTER_FRAME, _onEnterFrame);
		}
		private function _onEnterFrame(e:Event):void
		{
			var bmp:Bitmap = new Bitmap(new BitmapData(100, 100));
			//配列_arrにBitmapインスタンスを追加する
			_arr.push(bmp);
			//BitmapDataを開放
			bmp.bitmapData.dispose();
		}
	}
}

このままでは、メモリが増え続けていきます。
以下、メモリが残っていく結果です。

なぜなら、配列_arrの参照が切れていないので、Bitmapインスタンスがメモリに残っているから
以下のコードは、配列_arrに追加したBitmapインスタンスの参照を外しています。

private function _onEnterFrame(e:Event):void
{
	var bmp:Bitmap = new Bitmap(new BitmapData(100, 100));
	_arr.push(bmp);
	bmp.bitmapData.dispose();
	_arr.splice(0, 1);	//または_arr = [];
}

配列の参照を外すことでガベージコレクションの対象になり、無事にメモリ開放されました。

以下その結果。

※上記2つのwonderflを走らせると、なぜか、メモリが溜まっていってしまいます。

結果、インスタンスを使い終わったら以下を実行します。(赤字が追加部分)
・イベントを外す(removeEventListenerを実行)
・変数の参照を外す(null代入)+配列の参照がある場合は配列の参照を外す
・Bitmapインスタンスの場合、bitmapDataプロパティが存在していたら、開放する(dispose実行)

RSS Reader
RSSリーダーへの登録をお願いします。
トップへ戻るボタン

著者

大庭俊介
株式会社サイバーエージェント所属の紙デザイナー上がりのFlashデベロッパー。アメーバピグ内のコンテンツ企画、実装を手掛けています。金沢美術工芸大学出身。
follow twitter

おすすめ

イニシエーション・ラブ/ 乾 くるみ

最後の2行目を見たときにマジでビビり、最初からまた読み返してしまい、ネタばれのサイトに行き着く。

フィジカルコンピューティングを「仕事」にする

初めての共著作。Kinect作品PiggFighterの項目を執筆しています。

基礎からのiOS SDK

iPhone開発ド素人の僕が現在、勉強中の本。結構丁寧に書かれてあって分かりやすい。特にWebブラウザ作成のチュートリアル部分の説明でかなり理解が深まった。