アプリケーションがパフォーマンス上問題なく動作するためには、Unity がどのようにメモリを使い、割り当てているかを理解することが重要です。このセクションでは、Unity のメモリの仕組みを説明し、アプリケーションのメモリパフォーマンスを向上させる方法の理解を助けることを目的としています。
Unity では、3 つのメモリ管理レイヤーを使用して、アプリケーション内のメモリを処理します。
Mono と IL2CPP のスクリプト仮想マシン (VM) は、マネージメモリ システムを実装しています。このシステムは、スクリプトメモリシステムと呼ばれることもあります。これらの VM は、以下の異なるタイプに分けられた制御されたメモリ環境を提供します。
マネージメモリシステムは VM を使用しているため、メモリの割り当ての参照を自動的に追跡し、その生存期間を管理する環境が整っています。つまり、他のコードがメモリにアクセスしようとしているときに、アプリケーションがメモリを解放するタイミングが早すぎる可能性が低いことを意味します。また、コードから、または、使っていないメモリが積み重なってメモリにアクセスできない場合に発生する メモリリーク に対して、ある程度の保護手段があることも意味します。
Unity でマネージメモリを使用することは、アプリケーションのメモリを管理する最も簡単な方法ですが、いくつかのデメリットがあります。ガベージコレクターは便利ですが、メモリの解放と割り当てが予測できないため、動きが途切れる (メモリの解放と割り当てのために、ガベージコレクターが停止しなければならないときに発生) などのパフォーマンス問題につながる可能性があります。この予測不可能な問題を回避するために、C# アンマネージメモリレイヤー を使用することができます。
マネージメモリの仕組みについては、マネージメモリ のドキュメントを参照してください。
C# のアンマネージメモリレイヤー は、C#コードを書くことによってネイティブメモリレイヤーにアクセスし、メモリ割り当てを微調整することができます。
Unity コア API の Unity.Collections
名前空間 (NativeArray を含む) と Unity Collections パッケージ のデータ構造を使用して、C# のアンマネージメモリにアクセスできます。Unity の C# ジョブシステム、または Burst を使用する場合は、C# アンマネージメモリを使用する必要があります。これについての詳細は、ジョブシステム と Burst に関するドキュメントを参照してください。
Unity エンジンの内部 C/C++ コアは、独自のメモリ管理システムを持っており、これは ネイティブメモリ と呼ばれています。ほとんどの場合、このメモリタイプに直接アクセスしたり変更したりすることはできません。
Unity では、プロジェクト内のシーン、アセット、グラフィックス API、グラフィックスドライバー、サブシステムやプラグインのバッファ、メモリ割り当てなどをネイティブメモリ内に格納しているため、Unity の C# API を通して間接的にネイティブメモリにアクセスすることができます。つまり、Unity のネイティブコアにあるネイティブでパフォーマンスの高いコードのメリットを失うことなく、安全で簡単な方法でアプリケーションのデータを操作することができます。
ほとんどの場合、Unity のネイティブメモリを操作する必要はありませんが、プロファイラー、プロファイラーマーカー を使えば、アプリケーションのパフォーマンスにどのような影響を与えるかを確認することができます。