プロファイルしてみる
プロファイルの開始
それでは、サンプルプロジェクトを使用して実際にプロファイルを行ってみます。記事上部のリンクからサンプルプロジェクトをダウンロードし、Flash Builderに読み込んでください。
ProfileTuning.asを実行すると、真っ白な画面が表示されます。クリックすると、クリックした場所に黒い球体が描画されます。マウスの動きに応じて球体がマウスポインタの方に少しずつ動き、球体をクリックすると、クリックされた球体は消えます。
動作が確認できたら、いったんサンプルアプリケーションを終了して、今度はプロファイラを実行し、再度サンプルアプリケーションを操作してみます。プロファイル開始時のダイアログはデフォルトのままで構いません。クリックで球体を作るたびに、メモリの使用量がどんどん増えていくのが分かります。しかし、球体をクリックして消しても、メモリ使用量が減っていく様子はありません。ガベージコレクタを実行しても、やはりメモリ使用量は減りません。このサンプルアプリケーションは、メモリリークを起こしていることが分かります。
原因となる操作を特定する
このサンプルはActionScriptプロジェクトで作られており、またクラスは2つしか無いので、ライブオブジェクトビューで見るだけでも、球体を全て消した後もSphereクラスのインスタンスが減らずにそのまま残っているのがリークの原因ということはすぐ分かります。しかし実際のアプリケーションではもっとクラス数は多くなりますし、Flexプロジェクトの場合はFlex SDKに含まれるクラスが無数に生成されるので、ライブオブジェクトビューを一見してメモリリークの原因クラスを発見するのは難しいかもしれません。
このような場合、まずはアプリケーション上でどのような操作を行うとメモリリークを起こすのかを特定します。このサンプルであれば、「ステージをクリックで球体を作成」-「球体をクリックで球体を削除」という操作がこれに当たります。
メモリリークしているクラスを特定する
それでは、プロファイラをいったん終了して、もう一度プロファイルを開始します。このサンプルでは、「ステージをクリックで球体を作成」-「球体をクリックで球体を削除」という操作でメモリリークを起こすことが分かっているので、この操作を行う前と後で、クラスのインスタンスがどのように変化するかを調べれば、メモリリークの原因となっているクラスを特定できるはずです。
まず、メモリリーク前のメモリのスナップショットをキャプチャします。次に、サンプルアプリケーションを操作して、球体の作成と削除を何度か繰り返します。メモリ使用量が増えてきたのを確認したら、ガベージコレクタを実行します。これで、どこからも参照されていないオブジェクトは消去されました。最後にメモリリーク後のメモリのスナップショットをキャプチャして、プロファイルを終了します。
この2つのスナップショットをCtrl+クリックにて両方選択し、[不明なオブジェクトを検索]ボタン(
)をクリックすると、不明なオブジェクトビューが表示されます。このビューには、選択された2つのスナップショット間でインスタンス数が増えたクラスがリストされています。リークの原因となっているクラスの内容によっては非常に多くのクラスが表示されることもありますが、この中から怪しいクラスを探します。今回のサンプルでは、ここにリストされているクラスは、Class/Object/Functionを除くと、いずれもSphereクラス自身またはそのメンバであると思われるため、メモリリークしているクラスはSphereクラスであることが分かります。

