Loaderでロード中にメモリ不足になるとどうしようもないね…

以前、Loaderがロード完了イベントを発行しないことについて記事を書きましたが、少し時間がとれたので、前回よりも深く調べてみました。すると、ロード中にメモリが不足すると、ロード完了・失敗イベントのどちらも発生しないことがわかりました。今回、僕がテストコードを書いて試したのはModuleLoaderですが、おそらく素のLoaderやURLLoaderにも同様の問題があると思います。

ModuleLoaderは、モジュールのロード完了後に、モジュールのインスタンス化を行います。そして、インスタンス化が成功するとModuleEvent.READYを発行するようです。しかし、インスタンス化の途中でメモリが不足すると、READYイベントは発行されません。エラーなのだからModuleEvent.ERRORイベントが発行されるかと思いきや…こちらも発行されません。

内部的には、メモリ不足の例外が発生しているようなのですが、例外が発生しても、非デバッグ版のFlash Playerではエラーが表示されません。普通の利用者は全くメモリ不足を認識できない、という結構困った状況になります。また、メモリが不足すると、IEを巻き込んでFlash Playerがクラッシュすることもあります。

とはいえ、最近のPCはメモリをたくさん積んでいます。メモリ不足が原因でモジュールのロードに失敗するのは、よっぽどの場合に違いないと思うでしょう。

ところが、そうでもないようなのです。

IE + Flash Playerの環境でFlexアプリを動かすと、Flash Playerが確保したメモリが開放されないバグが報告されています。このへんに困っている人がいました。僕の手元では、Windows XP+IE8+Flash 10.0.42.34+Flex SDK 3.5.0の組み合わせで「Flexモジュールのロード→ブラウザのリロード」を繰り返すだけのFlexアプリを実行してみたところ、確実にメモリリークが発生しました。またリロードではなく、Flexモジュールのロード後に、ブラウザで別サイトに移動してもメモリリークが発生します。(OS,ブラウザ,Flash,FlexSDKの組み合わせが全く同じでも、発生しない環境があるようです。原因はFlash PlayerではなくIEやOS側にあるのかもしれません。調査中です)。

したがって、ブラウザを閉じずに、

Flexアプリ使う→他のサイトをブラウズ→Flexアプリ使う→ブラウズ…

のサイクルを繰り返していると、比較的簡単にメモリ不足に陥るようです。

対処方法はちょっと思いつきませんねぇ。Flash Player 10.1からはグローバルな例外をユーザーが処理する仕組みが入るのでなんとかなりそうですが。