FlashPlayer のガーベジコレクタについて

先日、「デストラクタを定義する」というエントリを書いた。丁度 Grant Skinner が、FlashPlayer のガーベジコレクタについての有用な記事を書いている。概要を意訳してみる。

Flash デベロッパActionScript 3 に移行するには、ガーベジコレクタの動作の仕組みについて理解しておく必要がある。ガーベジコレクタの知識無しに作成されたゲームやアプリケーションは、メモリや CPU といったシステムリソースを浪費し、そして、ユーザのシステムをハングアップさせる。

では、具体的に FlashPlayer のガーベジコレクタがどのように動作するのだろうか。まず、参照カウントを挙げている。これは delete ステートメントの解説に等しい。

参照カウントは ActionScript 1 から存在するシンプルな機構である。あるオブジェクトに対する参照を作成したら、参照カウントが増加し、参照を削除したら参照カウントは減少する。参照カウントが 0 になった時点でそのオブジェクトがガーベジコレクタによって削除される。FlashPlayer 6 と 7 には、XMLが円形に参照をした際にメモリが永遠に解放されない問題がある (デッドロック)。これは FlashPlayer 8 で実装された Mark Sweeping という機構により解決した。

Mark Sweeping の仕組みは Wikipedia のマーク・アンド・スイープの項 と合わせて理解したい。

FlashPlayer のガーベジコレクタは、ルートからオブジェクトを再帰的に走査し、オブジェクトのツリーを作成する。ツリーが作成された時点で、ルートから辿ることが不可能なオブジェクトはメモリから解放される。Mark Sweeping は正確である反面、CPU のコストが掛かる。

最後に、FlashPlayer 9 におけるガーベジコレクタの遅延と不確実性について。

最も重要で、理解しておきたいのは、FlashPlayer 9 のガーベジコレクタの動作が遅延することだ。FlashPlayer 9 においては、オブジェクトの全ての参照が削除されたとしても、オブジェクトはすぐには削除されないだろう。そして、幾らかの時間を置いてから削除が実行される。その間、サウンドが鳴り続けたり、onEnterFrame イベントが実行され続けるだろう。Flash デベロッパは、メモリが解放されるタイミングをコントロールする事は出来ない。従って、この不確実性を受け入れる以外の選択の余地はない。

メモリの解放に関する FlashPlayer 9 の仕様は要注意だろう。サウンドや onEnterFrame イベント終了時にはオブジェクトを不能にさせるべきだと Grant Skinner は言う。全くの同意見である。