Recent Changes

2011-11-05
2011-10-28
2011-09-19

Latest File Release

This Project Has Not Released Any Files

Wiki Guide

Side Bar

OutOfMemoryErrorについて

OutOfMemoryErrorって何なの?

android端末上では、Javaアプリケーションが利用可能なメモリの最大値には制限がかかっています。この制限は"最大ヒープサイズ"と呼ばれ、端末の機種ごとに値が固定されています(参照:Android 各機種 Heap Size 比較表の"MEM Dalvik max"値)。アプリケーションが使用するメモリの量が最大ヒープサイズ値を突破した場合、OufOMemoryErrorが発生します。この値をアプリケーション側から変更することは不可能です。

理不尽な仕様に思えるかもしれませんが、これはandroid OSや他の必要不可欠なアプリケーション(電話関連とか)を保護するための仕様です。(例えば、一昔前のブラクラのように、悪意のあるアプリケーションが無制限にメモリを消費することでOSそのものをフリーズさせてしまうようなことを、この仕様により防止できます)

Windows OS上で動作するネイティブアプリであるオリジナル版MikuMikuDanceは、Windowsマシンが搭載するメモリ(カタログスペック表に載っている物理メモリ+ディスク上の仮想メモリを合わせ、数GBレベル)を、OSが許す限り自由に使うことが可能です(ただし、32bit環境では2GB制限有り)。しかし、android端末上のアプリケーションでは上に書いた縛りがあるため、それより遥かに少ないメモリしか使用することができません。

回避する方法は無いの?

方法1 プレビューサイズを小さくする

設定画面の"Preview Size"設定でなるべく小さな値を指定することで、メモリ使用量を大幅に抑えることが可能です。

graph04.png

方法2 複雑なデータを読み込まない

非常に大きなモデルデータやモーションデータを読み込むと、メモリ使用量が増加します。

「非常に大きな」というのは曖昧な表現ですが、端末によって最大ヒープサイズがまちまちであり、かつユーザーが簡単に確認できる値でも無いため、「何MB以内なら大丈夫」と言い切ることができません。

方法3 正方形以外のテクスチャ画像は無駄にメモリを消費する

MMD-AR Viewer では、CGを描画する際にandroidが提供するOpenGL APIを使用しています。このAPIを使うと、テクスチャ画像の一辺の長さが2のn乗倍ピクセルの正方形ではない場合には、テクスチャ画像として読み込まれないという現象が発生します。 例えば、サイズが512 px × 512 pxや256 px × 256 pxの画像であれば正常にテクスチャとして表示されますが、サイズが500 px × 512 pxや、256 px × 512 pxといった画像については、そのままでは正常にテクスチャとして読み込むことができない可能性が高いです。

そのため、MMD-AR Viewer for Androidでは、内部的に画像のリサイズ処理を行なっています。

リサイズ時には一時的にリサイズ前の画像データとリサイズ後の画像データを両方メモリに保持する必要があるため、画像ファイルのサイズが大きい場合にはメモリの消費量が一時的に増加し、OutOfMemoryErrorが引き起こされる可能性が高まります。

予めテクスチャ画像を条件に合うようにリサイズしておけば、この現象を回避できると思います。ただ、テクスチャ画像ファイルのサイズが数MB未満であれば、実質上気にするレベルでは無いとは思いますが。

最後に

メモリー消費量の削減については、今後も継続して修正を行う予定です。

ただし、Windowsアプリケーション上で作成したファイルを読みこみ、リアルタイムでモーションを計算して描画するというアプリケーションの性質上、OutOfMemoryErrorが発生する可能性はある意味宿命です。(例えば動画やドキュメントファイルを表示するような、リアルタイムで描画する必要が無いアプリケーションだったら、部分的に読み込んでメモリに展開することでメモリの使用量を抑えることも可能なのですが・・・・モーションデータについては、今後ある程度の部分読み込みに対応できるかも)

まあ、利用可能な機種を絞り込んで、かつモデルデータやモーションデータを開発者側から提供するようなアプリケーションであれば、OutOfMemoryErrorの発生を100%完全に防ぐことが可能ですが・・・・そんな囲い込みモデルって楽しいの?

OutOfMemoryErrorの発生は「フリーダムさの代償」として受け取っていただければ幸いです。

(誤解の無いよう追記:実用アプリや有償アプリであれば、こんなことは書きません。)