[AS3] 外部から読込んだSWFをメモリから消し去るには [Edit]

Loaderクラスにより外部から読込んだSWFが要らなくなり、メモリから消したいときどのようにしたらよいでしょう。Loader.unload()メソッドを呼出すだけでは足りません。その場合に行うべき処理を確かめます。

01 アンロードする前にSWF内のオブジェクトはすべて止める

まず、Loader.unload()メソッドは、SWFのタイムラインの再生やその中のサウンド、ビデオを止める訳でも、メモリから直ちに消し去る訳でもありません。ただ、Laoderオブジェクトから子SWFのデータを除くだけです。[ヘルプ]の「Loader.unload()メソッド」の項には、つぎのような注意が記されています。

子SWFファイルを解放する前に、LocalConnection、NetConnection、NetStream、Soundオブジェクトなど、子SWFファイルのオブジェクト内のストリームをすべて明示的に閉じておくことをお勧めします。そうしなかった場合は、子SWFファイルが解放された後も、子SWFファイルのオーディオの再生が続く場合があります。

問題はサウンドにかぎりません。サウンド以外も、SWFの再生はメモリの中で続きます。ただ、サウンドは聴いてわかるのに対して、その他は見えないので気づかないだけです。AdobeのTechNote「ActionScript 3のLoader.unloadAndStopについて(Flash Player 10)」には、つぎのように説明されています(Loader.unloadAndStop()メソッドについては後述)。なお、ガベージコレクションについては、Adobeデベロッパーセンター「FlashでのActionScript 3デバッグの理解」をご参照ください。

Loader.unloadはLoaderオブジェクトの子を削除しますが、unloadされたオブジェクトは、ガベージコレクタによって廃棄されるまで、バックグラウンドで実行されます。

したがって、CPUやメモリが無駄に費やされるのを防ぎ、予期しない問題を避けるためには、アンロードする前にSWF内のオブジェクトはすべて止めるのが基本です。具体的にはつぎのような項目が挙げられます(moockblog「Things You Must Do Before Unloading a SWF File」参照)。

  • サウンドの再生を止める。
  • メインタイムラインやMovieClipインスタンスの再生を止める[*1]
  • ネットワークの接続を閉じる。
    • LoaderやURLLoader、Socket、XMLSocket、LocalConnection、NetConnections、NetStreamなど。
  • カメラ(Camera)やマイク(Microphone)など、周辺機器のオブジェクトを開放する。
  • SWFのイベントリスナーを削除する。
  • TimerオブジェクトやsetInterval()関数などのタイマーを止める。

02 Flash Player 10から備わったLoader.unloadAndStop()メソッド

Flash Player 10からLoader.unloadAndStop()メソッドが備わりました。Loader.unload()メソッドと同じアンロードに加えて、SWFに対してつぎに掲げる処理が行われます(なお、「CPU 使用率の最小化」の「オブジェクトのフリーズとフリーズ解除」参照)。

  • サウンドの再生を止める。
  • すべてのMovieClipインスタンスの再生を止める。
  • カメラ(Camera)やマイク(Microphone)のオブジェクトを開放する。
  • SWFのイベントリスナーを削除する。
    • StageオブジェクトやSWFのメインタイムラインに登録されたイベントリスナー。
    • DisplayObject.enterFrameDisplayObject.frameConstructedDisplayObject.exitFrameEventDispatcher.activateEventDispatcher.deactivateのイベントリスナー。
  • Timerオブジェクトのタイマーを止める。

具体的には、Loader.unloadAndStop()メソッドの呼出しによりLoaderInfo.unloadイベントが起きたとき、SWF内のオブジェクトを片っ端から探して、上記の停止と消去の処理を行います[*2]。その結果、無駄にCPUを費やすことが避けられます。とくに、ソースのFLAファイルが開けない外部SWFファイルを読込んだときには役立つでしょう。

しかし、外部SWFファイルが自らつくったものであれば、再生されているMovieClipやサウンド、ビデオが何かは把握しておくべきです。また、イベントリスナーについても、予め削除の処理を備え、いつ実行するか決めておくのが確実です。

また、Loader.unloadAndStop()メソッドも万能ではありません[*3]。このメソッドに頼りきらず、オブジェクトの停止と消去を自ら行えるようにすることが望ましいでしょう。


[*1] Flash Player 11には、再生中かどうかを調べる「MovieClip.isPlayingプロパティ」が備わりました。

[*2] 「ActionScript 3 の Loader.unloadAndStop について(Flash Player 10)」は、つぎのように説明します。

「unload」イベントがLoaderInfoクラスに送信されると、Flash Playerは可能な限り多くのオブジェクト(Sound、NetStream、EventListenerなど)の停止と消去を再帰的に試みます。

[*3] gskinner.com「Additional Information on Loader.unloadAndStop」参照。なお、クラウド番外地「制作記録 2010/08/18」は、Loader.unloadAndStop()で完全に削除されないSWFの事例を紹介しています。

コメント

この記事にコメントを書く

記事に対するテクニカルな質問はご遠慮ください(利用規約)。

その他の記事