# Unity のメモリ

> Manage and optimize memory usage in Unity applications.


**Frame:**
![](/api/media?file=/engine/6000.0/media/images/memory-in-unity-header.jpg)

アプリケーションがパフォーマンス上問題なく動作するためには、Unity がどのようにメモリを使い、割り当てているかを理解することが重要です。このセクションでは、Unity のメモリの仕組みを説明し、アプリケーションのメモリパフォーマンスを向上させる方法の理解を助けることを目的としています。

Unity では、3 つのメモリ管理レイヤーを使用して、アプリケーション内のメモリを処理します。

* [マネージメモリ](#managed-memory): マネージヒープと [ガベージコレクター](https://en.wikipedia.org/wiki/Garbage_collection_\(computer_science\)) を使用する制御されたメモリレイヤーです。自動的にメモリ割り当てを行います。
* [C# のアンマネージメモリ](#unmanaged-memory): Unity Collections 名前空間およびパッケージと組み合わせて使用できる、メモリ管理のレイヤーです。このメモリタイプは、メモリの未使用部分の管理に [ガベージコレクター](/engine/6000.0/manual/analysis/performance-memory-overview/managed-memory/garbage-collector.md) を使用しないため、"アンマネージ" と呼ばれています。
* [ネイティブメモリ](#native-memory): Unity がエンジンを実行するために使用する C++ メモリです。ほとんどの場合、このメモリには Unity ユーザーはアクセスできませんが、アプリケーションパフォーマンスのある面を微調整したい場合には、このメモリを知っておくと便利です。

## マネージメモリ

[Mono と IL2CPP](/engine/6000.0/manual/scripting/compilation-and-code-reload/backends.md) のスクリプト仮想マシン (VM) は、**マネージメモリ**システムを実装しています。このシステムは、スクリプトメモリシステムと呼ばれることもあります。これらの VM は、以下の異なるタイプに分けられた制御されたメモリ環境を提供します。

* **マネージヒープ**: VM が [ガベージコレクター](/engine/6000.0/manual/analysis/performance-memory-overview/managed-memory/garbage-collector.md) (GC) を使って自動的に制御するメモリのセクションです。このため、マネージヒープ上に割り当てられたメモリは、**GC Allocation** (GC メモリ割り当て) と呼ばれます。[プロファイラー](/engine/6000.0/manual/analysis/profiler.md) は、このような割り当ての発生を **GC.Alloc** サンプルとして記録します。
* **スクリプトスタック:** これは、アプリケーションがあらゆるコードスコープに出入りする際に構築され、開放されます。
* **ネイティブ VM メモリ:** Unity のスクリプトレイヤーに関連するメモリが含まれています。ほとんどの場合、ネイティブ VM のメモリを操作する必要はありませんが、コードが生成する実行コードに関連するメモリが含まれていることを知っていると便利です。特に、[ジェネリック](https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/types/generics) の使用、[リフレクション](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/reflection) が使用するタイプのメタデータ、VM の実行に必要なメモリが含まれていることを知っていると役に立ちます。

マネージメモリシステムは VM を使用しているため、メモリの割り当ての参照を自動的に追跡し、その生存期間を管理する制御された環境が整っています。つまり、他のコードがメモリにアクセスしようとしているときに、アプリケーションがメモリを解放するタイミングが早すぎる可能性が低いことを意味します。また、コードから、または、使っていないメモリが積み重なってメモリにアクセスできない場合に発生する [メモリリーク](https://en.wikipedia.org/wiki/Memory_leak) に対して、ある程度の保護手段があることも意味します。

Unity でマネージメモリを使用することは、アプリケーションのメモリを管理する最も簡単な方法ですが、いくつかのデメリットがあります。ガベージコレクターは便利ですが、メモリの解放と割り当てが予測できないため、スタッター (メモリの解放と割り当てのために、ガベージコレクターが停止しなければならないときに発生) などのパフォーマンス問題につながる可能性があります。この予測不可能な問題を回避するために、[C# のアンマネージメモリレイヤー](#unmanaged-memory) を使用することができます。

マネージメモリの仕組みの詳細は、[マネージメモリ](/engine/6000.0/manual/analysis/performance-memory-overview/managed-memory.md) のセクションを参照してください。

## C#のアンマネージメモリ

**C# のアンマネージメモリレイヤー**は、C# コードを書くという便利な方法でネイティブメモリレイヤーにアクセスし、メモリ割り当てを微調整することができます。

Unity コア API の `Unity.Collections `名前空間 ([NativeArray](/engine/6000.0/script-reference/unity-collections/native-array-1.md) を含む) と [Unity Collections パッケージ](https://docs.unity3d.com/Packages/com.unity.collections@latest) のデータ構造を使用して、C# のアンマネージメモリにアクセスできます。Unity の C# Job System、または Burst を使用する場合は、C# のアンマネージメモリを使用する必要があります。これについての詳細は、[ジョブシステム](/engine/6000.0/manual/scripting/optimization/job-system.md) と [Burst](http://docs.unity3d.com/Packages/com.unity.burst@latest) に関するドキュメントを参照してください。

## ネイティブメモリ

Unity エンジンの内部 C/C++ コアは、独自のメモリ管理システムを持っており、これは**ネイティブメモリ**と呼ばれています。ほとんどの場合、このメモリタイプに直接アクセスしたり変更したりすることはできません。

Unity では、プロジェクト内のシーン、アセット、グラフィックス API、グラフィックスドライバー、サブシステムやプラグインのバッファ、メモリ割り当てなどをネイティブメモリ内に格納しているため、Unity の C# API を通して間接的にネイティブメモリにアクセスすることができます。つまり、Unity のネイティブコアにあるネイティブでパフォーマンスの高いコードのメリットを失うことなく、安全で簡単な方法でアプリケーションのデータを操作することができます。

ほとんどの場合、Unity のネイティブメモリと相互作用する必要はありませんが、[プロファイラー](/engine/6000.0/manual/analysis/profiler/window.md)、[プロファイラーマーカー](/engine/6000.0/manual/analysis/profiler/markers.md) を使えば、アプリケーションのパフォーマンスにどのような影響を与えるかを確認することができます。また、Unity のネイティブメモリアロケーターの設定の一部を変更することで、アプリケーションのパフォーマンスを調整することもできます。詳細は、[ネイティブメモリ](/engine/6000.0/manual/analysis/performance-memory-overview/native-allocators.md) のセクションを参照してください。
