Adobe AIRアドベントカレンダーの一環として、「Flash Player/Adobe AIRのメモリリーク対策」を記事にまとめました。メモリリーク対策として弊社が取り組んでいる手法を紹介します。

メモリリーク対策の重要性

Flashコンテンツ/AIRアプリを長時間起動してるとメモリの使用量が増大し動作が不安定になることがあります。メモリ使用量の増大によってフレームレートの維持が難しくなったり、Flashコンテンツ/AIRアプリのクラッシュへとつながります。

Flashコンテンツの制作でメモリリーク対策を必要としなかった開発者は多いと思います。2000年代のフルFlashサイト全盛期に需要のあった広告系コンテンツ。それらは訴求力重視/公開期間が短めということもあってメモリリーク対策が求められる機会が少なかったのです。

2010年代になるとFlashコンテンツの用途が広がり、スマホアプリやサイネージ、ゲームコンテンツなど長時間起動を前提としたコンテンツの需要が拡大しました。そのことによってメモリリーク対策が求められる場面が増えたといえるでしょう。

※Flashは世間ではメモリの使用量が大きいと言われますが、決してHTML5に比べてメモリの使用量が大きいわけではありません。設計次第でHTML5も同様にメモリの使用量が大きくなります(むしろHTML5のほうがメモリリーク対策のツールが揃っておらず対策が困難なケースがあります)

方針

省メモリ対策のActionScriptの設計として「使い終わったら消す」ことを基本方針にしています。具体的には画面遷移したときに以前の画面が不要になります。その時に以前の画面で使われていたオブジェクトを取り除きます。

参照破棄のメソッドdispose()メソッドを用意する

ActionScriptではメンバー変数の参照が外れたり、DisplayListから外れるとガベージコレクションの対象となります。この「参照が外れた状態」を作るために一番確実な方法は明示的に破棄用のメソッドを実装することです。

弊社では、一般的な慣習に従ってdispose()という名前のメソッドをカスタムクラスにはほぼ全部に用意し、不要になったタイミングで明示的に呼び出すようにしています。dispose()というメソッド名はビルトインのBitmapDataクラスにも存在しますし、ProgressionやStarlingなどのデファクトスタンダードな(だった)ActionScriptのフレームワークに標準搭載されています。

dispose()メソッドで実装するポイント

dispose()メソッドでは主に次の処理を記述します。メンバー変数にnullを代入することで参照を断ち切ることができます。

  • メンバー変数にnullを代入する
  • メンバー変数で破棄可能なものは破棄する (子にdispose()を実行する)
  • 登録されたイベントを解除する

これを簡単に記述するためのツールを用意しているので([AS3 Coding Tools] Property Disposer – wonderfl)、よければご利用ください。

以下は実際のプロジェクトでのdispose()メソッドのコード例です。

画面やクラスはツリー上に構築しているのですが、頂点のインスタンスのdispose()メソッドを叩けば、子→孫→曾孫と階層構造的にdispose()メソッドが呼ばれます。こうすれば画面遷移のときに、一つのdispose()メソッドを呼び出すだけで、関連する画面要素の隅々まで参照を破棄することができます。

次のページでは、Flash Builder 4.7 プロファイラとScoutを利用したメモリリークの対策方法を解説します。