Memory constraints in Unity Web can restrict the complexity of the content you run.
Web content runs in the browser. The browser allocates the memory in its memory space that your application needs to run your content. The amount of available memory varies depending on:
Note: For information on security risks related to Web memory, refer to Security and Memory Resources.
The following areas of Unity Web content require the browser to allocate significant amounts of memory.
Unity はメモリヒープを使用して、すべての Unity エンジンランタイムオブジェクトを格納します。これには、マネージオブジェクト、ネイティブオブジェクト、ロードされたアセット、シーン、シェーダーなどが含まれます。これは、他のプラットフォームで Unity プレイヤーが使用するメモリのようなものです。
Unity のヒープは、割り当てられたメモリの連続したブロックです。Unity は、アプリケーションのニーズに合わせて、ヒープの自動サイズ変更をサポートしています。ヒープサイズは、アプリケーションが実行すると拡張され、最大 2GB まで拡張できます。Unity はこのメモリヒープを Memory オブジェクト として作成します。Memory オブジェクトの buffer プロパティはサイズ変更可能な ArrayBuffer で、WebAssembly コードがアクセスするメモリの生のバイトを保持します。
ヒープの自動リサイズは、ブラウザーがアドレス空間の連続したメモリブロックの割り当てに失敗すると、アプリケーションがクラッシュする原因となります。このような理由から Unity のヒープサイズをできるだけ小さくしておくことが重要です。したがって、アプリケーションのメモリ使用量を計画する際には注意が必要です。Unity のヒープサイズをテストしたい場合は、プロファイラー を使って、メモリブロックの内容をプロファイルすることができます。
You can control the initial size and growth of the heap by using the Memory Growth Mode options in the Web Player Settings. The default options are configured to work well for all desktop use cases. However, for mobile browsers you need to use the advanced tuning options. For mobile browsers, it’s recommended to configure the Initial Memory Size to the typical heap usage of the application.
When you create a Unity Web build, Unity generates a .data
file. This contains all the Scenes and Assets the application needs to launch. Because Unity Web doesn’t have access to the real file system, it creates a virtual memory file system, and the browser unpacks the .data
file here. The Emscripten framework (JavaScript) allocates this memory file system in the browser memory space. While your content runs, the browser memory keeps the uncompressed data. To keep both download times and memory usage low, try to keep this uncompressed data as small as possible.
メモリ使用量を削減するために、アセットデータを AssetBundle (アセットバンドル) にまとめることができます。アセットバンドルを使うと、アセットのダウンロードを完全に制御することが可能になります。アプリケーションがアセットをダウンロードするタイミングや、ランタイムがアセットをアンロードするタイミングを制御できます。未使用のアセットをアンロードすると、メモリを解放できます。
AssetBundles
は、Unity のヒープに直接ダウンロードされます。そのため、ブラウザーが余分な割り当てをすることはありません。
Enable Data Caching to automatically cache the Asset data in your content on the user’s machine. This means you don’t need to re-download that data during later runs. The Unity Web loader implements Data Caching with the IndexedDB API. This option lets you to cache files which are too large for the browser to cache natively.
Data caching enables the browser to store application data on the user’s machine. Browsers often limit the amount you can store in their cache and the maximum file size that can be cached. This is often not enough for an application to run smoothly. The Unity Web loader Caching with the IndexedDB
API that lets Unity store the data in the IndexedDB instead of the browser cache.
データキャッシングオプションを有効にするには、File > Build Settings > Player Settings > Publishing Settings の順に移動します。
ガベージコレクションとは、使われていないメモリを探し出して解放するプロセスです。ガベージコレクターは、未使用のメモリを収集すると、Unity のヒープ内で再割り当てします。次に、ガベージコレクターはスタックを検査し、ロードされたオブジェクト参照を登録します。ガベージコレクターは、参照されなくなったオブジェクトを見つけると、そのオブジェクトによって使用されていたメモリを解放します。
For an overview on how Unity garbage collection works, refer to Automatic Memory Management. Web garbage collection runs when the stack is empty. The stack is a part of the Unity heap but not the heap itself. As you cannot debug in JavaScript, the garbage collector will only run in Web in situations where the stack is empty. This currently happens once after every frame.
他のほとんどのプラットフォームでは、ガベージコレクション処理 が異なり、コレクターはスタックを検査できるように実行中のすべてのスレッドを一時停止します。Unity プロファイラー を使用してガベージコレクション処理をデバッグできます。
The garbage collector runs on the main thread. That is, if you have a long-running loop, the following code might fail when you run it on Web because the collector doesn’t get a chance to run the garbage collector between iterations of the loop. This means the garbage collector can’t free up memory that the intermediate string objects use, and runs out of memory in the Unity heap.
string hugeString = "";
for (int i = 0; i < 100000; i++)
{
hugeString += "foo";
}