こんにちは、新米FDのkoyuです。
今回のエントリーは世知辛い社会から魂の解放、いや、パンパンになったメモリの解放についてです。

ActionScript3.0でスライドショーなど動的に画像をロードするようなコンテンツを作成する場合に画像をロードし、removeChildしますよね?
しかし、画像に対しての参照が残っていた場合に、読み込んだLoaderやDisplayObjectをremoveChildをしただけではメモリが解放されず、ガンガン膨らんできます。
その様はまるで我が国の国債の発行残高のようです。結果として挙動が悪くなったり、ブラウザが落ちたりします。

では、参照が残るとはどういうことでしょうか?
例として挙げられるのは

    ・addEventListenerをしている場合
    ・変数に代入している場合
などです。

かく言う、私はハマってしまいして、その経験から本エントリーを書いた次第です。 それでは見ていきましょう

Here We Go!!

雑に言うとメモリの解放をするには・・・

    単にコンテンツをremoveChildってやると変数やイベントリスナー等の参照残りまくって、メモリがアボンするので、removeChild後に参照していた変数にnull突っ込む、イベントリスナーはremoveEventListenerするか、または、弱参照として登録しておく。ただ、参照を外したからといって直ぐにメモリが解放されることはなく、ガベージコレクションの起動を待つことになる。

メモリの解放とはどういうことでしょうか?
以下詳しく順を追ってみていきましょう

1:メモリとは・・・

    ◆コンピュータ内でデータやプログラムを記憶する装置です。
    ◆ActionScriptでは変数宣言(変数を作成)をするとメモリ上で作成され、メモリ内の値を表す名前となるので変数があるという事はメモリを使っているということになります。

2:メモリの解放とは・・・

    ◆作業用に確保されているメモリを不要になった時に解放することです。
    ◆ActionScriptでは参照を外し、メモリ上から削除することです。

3:メモリを解放したいけど、どうしよう?

    ◆メモリを解放するにはガベージコレクションという機能を利用します。
    ◆ガベージコレクションは一定のタイミングで起動し、変数を保持しているオブジェクト(スコープ)を調べていって、それが、参照されていないと分かれば、メモリ上から削除します。

4:参照とは?

    ◆参照とは、生成されたインスタンスのメモリ上の格納位置を示す値のことです。インスタンスの操作は、必ずこの参照を介して行われます。(JAVAの説明より)
    ◆自分としてはオブジェクトと変数の関連付けだと思ってます。

5:参照を外すとは?

    ◆変数とオブジェクトの関連付けを無効にするということ。具体的にコードで言うと変数にnullを代入します。null参照の変数のメソッドは呼ぶことができなくなるので、nullを代入する前にremoveEventListenerやremoveChildをして他の参照を外しておきましょう(nullのプロパティにアクセスをすると「#1009: null のオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。」というエラーが出てきます)
    しかし、これでは関連付けが無効になっただけで(参照がされなくなった)、変数そのものは削除されたわけではありませんので注意が必要です。
    →直ぐにメモリから解放されるわけではありません。
    ◆変数をこの状態にしておき、起動されるはずのガベージコレクションを待ちます。ガベージコレクションの起動のタイミングはkamijoさんのブログによりますと

      ・新しくメモリの割り当てが要求された場合
      ・割り当てたメモリの残りの容量が少なくなっている
    上記の2点が重なった時だそうです。基本的にはこのタイミングでガベージコレクションが起動してメモリを解放することとなります。


以下雑感です。
難しい。スコープチェーンやアクティベーションオブジェクトってなに?調べないと。
使わなくなった参照は即外せと。気にしたことなかった・・、イベントリスナーとかaddしっぱなしだったわ。Event.INITとか一回しか使わないのは実行と同時に即remove。

今回自分が実装した方法は、動的に読み込むオブジェクトのクラスにはクラスメンバをremoveした後にnullを代入するもの、addEventListenerした関数をremoveEventListenerで参照外すメソッドを書いておいて、stageから削除するタイミングでメソッド実行する。
addEventListenerには弱参照の利用をす方法もあります。
addEventListenerの弱参照とはaddEventListenerの第5引数にリスナーへの参照を強弱のパラメーターで与えることがでます。弱参照を与えるとremoveEventListenerを明示しなくても、ガベージコレクションの対象とすることができます。

参考URL
Flash Player 9 のガーベジコレクション
イベントリスナ (AS3) とガーベジコレクション
Flash MXにおけるスコープチェーンとメモリの浪費
AS3メモ ガベッジコレクションについて
ActionScript 3.0 コンポーネントリファレンスガイド addEventListener()

HTML5飯