4-5.使えるメモリ量が少ない

コードが正しくてもメモリを使いすぎると動かない

samplejpg

JavaScriptで組む比較的大規模なプログラムでも、コード自体が数メガバイトもメモリを消費する事は殆どありません。 しかし、画像ファイルや音声ファイルを多用すると数十メガバイト程度のメモリは簡単に消費されます。

PC/Macで動作するブラウザでは、その程度のメモリ消費量は、通常、問題にはなりませんが、メモリ搭載量の少ないスマートフォンでは、その程度のメモリ消費でも、プログラムが動作しなくなることがあります。

このため、作成するゲームをスマートフォンでも動作させようとする場合には、消費されるメモリ量を低く抑える工夫が必要になる場合があります。

強制的にメモリ不足にしてどうなるかを見る

以下のサンプルページでは、320x240の領域として確保したcanvasの全体をgetImageDataで何回も取り込む事で、強制的にメモリ不足を発生させます。 一回のgetImageDataでは、最低300kB程度のメモリが消費される筈ですが、ブラウザによっては、それ以上のメモリが消費されます。

PCで動作するブラウザでは、Firefoxが800回程度の取り込みでメモリ不足になった以外は、数千回程度の取り込みが可能でした。

一方で、Androidエミュレータのブラウザでは、百数十回程度の取り込みでブラウザはクラッシュしてしまいました。

このように、PCとスマートフォンでは使えるメモリ量は大きく異なります。 一度、以下のサンプルページで、PC/Macとスマートフォンの違いを確認してみて下さい。

サンプルページを見る

メモリ消費量を減らすように心がける

上記のコードでは、getImageDataで取得したデータは使用されることはありませんが、明確な削除処理も行われていません。 このため、ブラウザは使用されることの無いメモリを破棄する事ができず、メモリを使い切ってしまいます。

JavaScriptには、使われなくなったメモリを自動的に破棄する機構があります。 しかし、この機構を動作させるためには、データを使わなくなった、という事を間接的に知らせてやる必要があります。

C++であれば、newで確保したメモリはdeleteで開放できます。しかし、JavaScriptではnewは使えますが、deleteは使えません。 このため、例えば、data = new Array(1024)として確保した配列領域を開放させたい場合には、data = 0等の動作上は意味の無い処理を追加する必要があります。

また、処理の単純化のためには、プログラムで使用する全ての画像は最初に読み込んでおきたい所ですが、そういう処理にすると必要なメモリ量は増大します。 このため、メモリ消費量を減らすためには、画像データは必要になった時点で読み込み、かつ、その時点で不要なデータは上記のようにして強制的に削除する、といった特別な配慮が必要になります。