Hero background image

Unity のメモリプロファイリングツールを使用して、メモリ使用量をプロファイリングおよび分析します。

このページでは、Unity のアプリケーションでのメモリ使用量を分析するための 2 つのツールに関する情報を提供します。メモリプロファイラー パッケージとメモリプロファイラー モジュールです。
このウェブページは、お客様の便宜のために機械翻訳されたものです。翻訳されたコンテンツの正確性や信頼性は保証いたしかねます。翻訳されたコンテンツの正確性について疑問をお持ちの場合は、ウェブページの公式な英語版をご覧ください。
メモリプロファイラーのウォークスルーとチュートリアル | Unity

-

さまざまなプラットフォームやデバイス向けにゲームのパフォーマンスをプロファイリングし、磨きをかけることで、プレイヤーベースを拡大し、成功の可能性を高めることができます。

-

ここにある情報は、ゲーム開発、プロファイリング、最適化の分野で外部および内部の Unity 専門家によって作成された電子書籍 Unity ゲームのプロファイリングに関する究極のガイド (Unity 6 エディション) から抜粋されたものです。

メモリプロファイリングとは何ですか?

メモリプロファイリングは、ランタイムパフォーマンスとはほとんど関係がありませんが、ハードウェアプラットフォームのメモリ制限に対してテストする場合や、ゲームがクラッシュする場合に役立ちます。メモリ使用量を実際に増加させる変更を行うことで、CPU/GPU パフォーマンスを向上させたい場合にも関連する可能性があります。

Unity のアプリケーションでのメモリ使用量を分析する方法は 2 つあります。

- メモリプロファイラー モジュール:これは、アプリケーションが通常のプロファイラーでメモリを使用している場所に関する基本情報を提供するビルトインプロファイラーモジュールです。

- メモリプロファイラー:これは、プロジェクトに追加できるUnityパッケージとして利用可能な専用ツールです。Unityエディターに追加のメモリプロファイラーウィンドウを追加し、アプリケーションのメモリ使用量をさらに詳細に分析するために使用できます。スナップショットを保管して比較することでメモリリークを見つけたり、メモリレイアウトを確認してメモリの断片化の問題を見つけたりできます。このガイドの後半でさらに詳しく説明しますが、ここでは考慮すべき一般的な点に焦点を当てます。

これらのツールはどちらも、メモリ使用量を監視し、アプリケーションのメモリ使用量が予想以上に高い領域を特定し、メモリの断片化を見つけて改善することを可能にします。

メモリプロファイラーパッケージは、UnityアプリケーションとUnityエディターのメモリ使用量を検査するために使用できるツールです。
メモリプロファイラーパッケージは、UnityアプリケーションとUnityエディターのメモリ使用量を検査するために使用できるツールです。

メモリバジェットを把握して定義する

ターゲットデバイスのメモリ制限を理解し、予算を立てることは、マルチプラットフォーム開発にとって重要です。シーンやレベルを設計する際には、各ターゲットデバイスに設定されたメモリ予算を守る必要があります。制限とガイドラインを設定することで、アプリケーションが各プラットフォームのハードウェア仕様の範囲内でうまく機能することを保証できます。

デバイスのメモリ仕様は開発者ドキュメントで確認できます。

メッシュやシェーダーの複雑さ、テクスチャ圧縮に関するコンテンツ予算を設定することも有用です。これらはすべて、どれだけのメモリが割り当てられるかに影響します。これらの予算の数値は、プロジェクトの開発サイクル中に参照できます。

物理RAM制限を決定する

各プラットフォームにはメモリ制限があるため、アプリケーションは各ターゲットデバイスのメモリ予算が必要です。メモリプロファイラーを使用して、メモリ使用量のキャプチャされたスナップショットを確認します。ハードウェアリソーススナップショット(下の画像を参照)は、物理ランダムアクセスメモリ(RAM)とビデオランダムアクセスメモリ(VRAM)のサイズを示しています。この数値は、そのスペースのすべてが使用可能であるわけではないことを考慮していません。ただし、作業を開始するための便利な概算値を提供します。

ここに表示される数値は常に全体像を示すわけではないため、ターゲットプラットフォームのハードウェア仕様をクロスリファレンスすることをお勧めします。開発者キットのハードウェアは、時にはより多くのメモリを持っているか、統一メモリアーキテクチャを持つハードウェアで作業している可能性があります。

ハードウェアリソースのスナップショットは、スナップショットがキャプチャされた時点におけるデバイスのRAMとVRAMの数値を示しています。
ハードウェアリソースのスナップショットは、スナップショットがキャプチャされた時点におけるデバイスのRAMとVRAMの数値を示しています。

最低 RAM 仕様を決定します。

サポートする各プラットフォームのRAMの最低仕様を持つハードウェアを特定し、これをメモリ予算の決定に役立ててください。すべての物理メモリが使用可能であるとは限らないことを忘れないでください。例えば、コンソールには古いゲームをサポートするためにハイパーバイザーが実行されている可能性があり、これが総メモリの一部を使用することがあります。特定のシナリオに応じて、チームが使用するためのパーセンテージ(例:総計の80%)を考えてみてください。モバイルプラットフォームの場合、より高品質で機能をサポートするために、より高性能なデバイスを持つユーザー向けに複数の仕様の層に分割することも検討できます。

大規模なチームのためのチームごとの予算を考慮してください

メモリ予算が定義されたら、チームごとのメモリ予算を設定することを検討してください。例えば、環境アーティストには、読み込まれる各レベルやシーンに使用するための特定のメモリ量が与えられ、オーディオチームには音楽や効果音のためのメモリ割り当てが与えられます。これは堅苦しく見えるかもしれませんが、リソースのコストに対して行われるクリエイティブな決定を通知するためのガイドラインとして考えてください。

プロジェクトが進行するにつれて、予算に柔軟性を持つことが重要です。あるチームが予算内で収まった場合、ゲームの開発している領域を改善できる場合は、余剰を別のチームに割り当ててください。

ターゲットプラットフォームのメモリ予算を決定し設定したら、次のステップはプロファイリングツールを使用してゲーム内のメモリ使用量を監視および追跡し、情報に基づいた決定を下し、必要に応じて行動を取ることです。

メモリプロファイリングのためのいくつかのヒント

メモリ使用量がプラットフォームの予算に近づき始める高レベルの判断を行うには、次の「ナプキンの裏側」計算を使用します:

システム使用メモリ(またはシステム使用が0の場合は総予約メモリ) + 未追跡メモリの概算バッファ / プラットフォームの総メモリ

この数値がプラットフォームのメモリ予算の100%に近づき始めたら、メモリプロファイラパッケージを使用してその理由を特定してください。

Unity 6では、メモリプロファイラモジュールの多くの機能がメモリプロファイラパッケージによって置き換えられていますが、メモリ分析の努力を補完するためにモジュールを使用することはできます。例:

- GC アロケーションを特定するには:これらはモジュールに表示されますが、プロジェクト監査ツールやディーププロファイリングを使用すると、追跡が容易になります。

- ヒープの使用済み/予約サイズをすばやく確認するには

- シェーダーのメモリ分析

- メモリプロファイラモジュールの詳細ビューを使用して、最もメモリを使用しているメモリツリーを掘り下げて確認します。

Unity Profilerの追加のユースケースや機能を探るのに役立つリソースをいくつか紹介します:

- Unityマニュアルのプロファイラ概要

- Unityにおけるプロファイリングの概要

- ゲームのプロファイリングと最適化の方法

通常、メモリが豊富に利用できる強力な開発者システムを使用してプロファイリングを行いたいと思うでしょう(大きなメモリスナップショットを保存したり、それらのスナップショットを迅速に読み込んだり保存したりするためのスペースが重要です)。

メモリプロファイリングは、CPUおよびGPUプロファイリングとは異なるもので、追加のメモリオーバーヘッドが発生する可能性があります。高性能デバイス(より多くのメモリを持つ)でメモリをプロファイリングする必要があるかもしれませんが、特に低性能ターゲット仕様のメモリバジェット制限に注意してください。

品質レベル、グラフィックティア、アセットバンドルのバリアントなどの設定は、より強力なデバイスで異なるメモリ使用量を持つ可能性があります。そのことを考慮に入れて、メモリプロファイリングから最大限の効果を得るために留意すべき詳細を以下に示します:

- 品質およびグラフィック設定は、シャドウマップに使用されるレンダーテクスチャのサイズに影響を与える可能性があります。

- 解像度スケーリングは、画面バッファ、レンダーテクスチャ、およびポストプロセスエフェクトのサイズに影響を与える可能性があります。

- テクスチャ設定は、すべてのテクスチャのサイズに影響を与える可能性があります。

- 最大LODは、モデルやその他に影響を与える可能性があります。

HD(高解像度)およびSD(標準解像度)バージョンのようなアセットバンドルのバリアントがあり、ターゲットデバイスの仕様に基づいてどちらを使用するかを選択すると、プロファイリングしているデバイスに基づいて異なるアセットサイズが得られる可能性があります。

- ターゲットデバイスの画面解像度は、ポストプロセスエフェクトに使用されるレンダーテクスチャのサイズに影響を与えます。

- デバイスのサポートされているグラフィックス API は、どのバリアントをサポートしているか(またはサポートしていないか)に基づいてシェーダーのサイズに影響を与える可能性があります。

- 異なる品質とグラフィック設定、さらに AssetBundle のバリアントを使用する階層化システムは、より広範囲のデバイスをターゲットにするための素晴らしい方法です。

例えば、4GB のモバイルデバイスで HD バージョンの AssetBundle をロードし、2GB のデバイスで SD バージョンをロードできます。ただし、上記のメモリ使用量の変動を考慮し、異なる画面解像度やサポートされているグラフィックス API を持つデバイスの両方をテストすることを確認してください。

注:Unity エディターは、エディターとプロファイラーからロードされる追加のオブジェクトのため、一般的に常に大きなメモリフットプリントを示します。さらに、テクスチャのメモリフットプリントは、すべてがエディターで読み取り/書き込みを有効にするよう強制されるため、高くなります。

Memory Profiler モジュールを使用すると、システムに割り当てたメモリの量を簡単に確認できます。
Memory Profiler モジュールを使用すると、システムに割り当てたメモリの量を簡単に確認できます。

Memory Profiler のパッケージ

Memory Profiler パッケージは、プロジェクトのメモリ使用量を理解し、最適化するのに役立ちます。これにより、Unity エディター内およびターゲットデバイス上で実行中のプレイヤーのビルドの特定の瞬間にアプリケーションのメモリの「スナップショット」をキャプチャできます。

スナップショットは、メモリがどのように利用されているかの包括的な内訳を提供し、エンジン全体の割り当てを示します。これにより、過剰または不必要なメモリ使用の原因を特定し、メモリリークを追跡し、ヒープの断片化などの問題を検査できます。

Memory Profiler パッケージをインストールした後、ウィンドウ > 分析 > Memory Profiler を介して開きます。

Memory Profiler の上部メニューバーでは、プレイヤーの選択ターゲットを変更し、スナップショットをキャプチャまたはインポートできます。左上隅のターゲット選択ドロップダウンでは、Memory Profiler をリモートデバイスに接続することで、ターゲットハードウェア上で直接メモリをプロファイルできます。Unity エディターでのプロファイリングは、エディターや他のツールによって追加されたオーバーヘッドのため、正確な数値を提供しないことに注意してください。

プレイヤーの選択を変更し、メモリスナップショットをキャプチャまたはインポートします。
プレイヤーの選択を変更し、メモリスナップショットをキャプチャまたはインポートします。

スナップショット コンポーネント

Memory Profiler ウィンドウの左側には、スナップショットコンポーネント があります。これを使用して、保存されたメモリスナップショットを管理し、開いたり閉じたりします。スナップショットコンポーネントは、シングルスナップショットと比較スナップショットの2つのビューを提供します。

Profile Analyzer と同様に、Memory Profiler は、2つのメモリスナップショットを並べて読み込み、比較することを可能にします。この比較を使用して、時間の経過に伴うメモリの成長を追跡したり、シーン間の使用状況を分析したり、潜在的なメモリリークを特定したりできます。

メモリプロファイラーには、メモリスナップショットを掘り下げるためのメインウィンドウにいくつかのタブがあります。主要なものはサマリーUnityオブジェクト、およびメモリのすべてです。これらのオプションを詳細に見ていきましょう。

複数のメモリスナップショットを管理できます。
複数のメモリスナップショットを管理できます。

サマリー タブ

サマリータブは、メモリキャプチャが行われた瞬間のプロジェクトのメモリ使用状況の高レベルのスナップショットを提供します。詳細な分析に入らずに、迅速で情報豊富な概要を得たいときに最適です。

このビューは、主要なメトリックを強調表示し、潜在的なメモリの問題や予期しない使用パターンを迅速に特定するのに役立ちます。スナップショットを比較したり、時間の経過に伴うメモリ使用状況をデバッグしたりする際に特に便利です。いくつかの主要なセクションを見てみましょう。

ヒント:右側のパネル(下の画像を参照)には、スナップショットに関する役立つコンテキスト情報が表示されます。これらは、問題の可能性を警告したり、結果の解釈をガイドしたりすることができます。

デバイス上のメモリ使用状況:これは、物理メモリにおけるアプリケーションのフットプリントを示します。キャプチャ時にメモリに常駐しているすべてのUnityおよび非Unityの割り当てが含まれます。

割り当てられたメモリの分布:このビューは、割り当てられたメモリが異なるメモリカテゴリにどのように分配されているかを視覚化します。

未追跡*メモリバーに注意してください。これは、Unityがそのメモリ管理システムを通じて追跡しないメモリに対応します。そのような割り当ては、ネイティブプラグインやドライバーから来る可能性があります。プラットフォーム固有のプロファイラーを使用して、ターゲットデバイスの未追跡メモリ使用量を分析します。

マネージヒープの利用状況:このビューでは、UnityのスクリプトVMが管理するメモリの内訳が表示されます。これには、マネージオブジェクトに使用されるマネージヒープメモリ、以前にオブジェクトによって使用されたか、最後のヒープ拡張中に予約された可能性のある空のヒープスペース、そして仮想マシン自体が使用するメモリが含まれます。

トップUnityオブジェクトカテゴリ:これにより、スナップショット内で最もメモリを使用しているUnityオブジェクトのタイプ(例:Texture2D、メッシュ、GameObject)が表示されます。

サマリタブには、そのスナップショットがキャプチャされた時点のメモリの概要が表示されます。
サマリタブには、そのスナップショットがキャプチャされた時点のメモリの概要が表示されます。

オブジェクトタブ

Unityオブジェクトタブには、メモリを割り当てたUnityオブジェクト、オブジェクトが使用するネイティブメモリとマネージメモリの量、および合計が表示されます。この情報を使用して、重複したメモリエントリを排除できる領域を特定したり、最もメモリを使用しているオブジェクトを見つけたりします。検索バーを使用すると、入力したテキストを含むテーブル内のエントリを見つけることができます。

デフォルトでは、テーブルはすべての関連オブジェクトを割り当てサイズの降順でリストします。列ヘッダー名をクリックすると、その列でテーブルをソートしたり、列が昇順または降順でソートされるかを変更できます。

メモリ使用量を最適化し、メモリ予算が限られているハードウェアプラットフォーム向けにメモリをより効率的にパックすることを目指す際に、これを活用してください。

Unityオブジェクトタブでは、キャプチャされたスナップショットのメモリ使用量を高い粒度で掘り下げることができます。
Unityオブジェクトタブでは、キャプチャされたスナップショットのメモリ使用量を高い粒度で掘り下げることができます。

メモリプロファイリング技術とワークフロー

メモリプロファイラーのスナップショットを分析して、高メモリ使用領域を特定することから始めます。メモリプロファイラーのスナップショットをキャプチャまたはロードすると、Unityオブジェクトタブを使用して、メモリフットプリントサイズの大きい順にカテゴリを検査します。

プロジェクトアセットは、しばしばメモリの最大消費者です。テーブルモードを使用して、テクスチャ、メッシュ、オーディオクリップ、レンダーテクスチャ、シェーダーバリアント、および事前割り当てされたバッファを見つけます。これらは、メモリ使用量を最適化する際に最初に着手するのに適した候補です。プロジェクト監査ツールは、アセットのメモリ使用量を削減する方法についての推奨事項を提供できるため、ここでの優れた補完ツールです(アセットがインポート設定インスペクターで適切に設定されていることを確認することが良い出発点です)。

メモリリークの特定

メモリリークとは、未使用のアセット、オブジェクト、またはリソースがメモリから適切に解放されない状況です。これにより、メモリ使用量が徐々に増加し、パフォーマンスの問題やクラッシュが発生する可能性があります。

メモリリークは通常、次のような場合に発生します:

- オブジェクトがコードを通じて手動でメモリから解放されない。

- オブジェクトが意図せずメモリに残っているのは、別のオブジェクトがまだその参照を保持しているためです。

メモリプロファイラーには、特定の時間枠内で2つのスナップショットを比較することによってスナップショットの比較モードがあり、メモリリークを見つけるのに役立ちます。この比較により、解放されるべきオブジェクトがメモリに残っていることが明らかになります。

Unityゲームにおけるメモリリークの一般的なシナリオは、シーンをアンロードした後です。アンロードされたシーンのオブジェクトは、それらへの参照がまだ存在する場合、正しくガベージコレクトされない可能性があります。

アプリケーションの生存期間にわたる繰り返しメモリ割り当ての特定

複数のメモリスナップショットの差分比較を通じて、アプリケーションの生存期間中の継続的なメモリ割り当てのソースを特定できます。

以下のセクションでは、プロジェクト内のマネージヒープ割り当てを特定するためのいくつかのヒントを提供します。

2つのスナップショットを比較して、違いを確認します。
2つのスナップショットを比較して、違いを確認します。

メモリプロファイラー モジュールに表示される管理された割り当て

Unityプロファイラー内のメモリプロファイラーモジュールは、フレームごとのマネージ割り当てを赤い線で表します。通常は0であるべきなので、その線のスパイクは、マネージ割り当てのために調査すべきフレームを示します。

「GC Allocated in Frame」に見られるスパイクにより、マネージ割り当てを調査するためのポインターが与えられます。
「GC Allocated in Frame」に見られるスパイクにより、マネージ割り当てを調査するためのポインターが与えられます。

「CPU Usage Profiler」モジュールの「Timeline」ビュー

CPU使用率プロファイラーモジュールのタイムラインビューは、マネージされたものを含む割り当てをピンクで表示し、注目しやすくしています。

マネージアロケーションは「Timeline」ビューにピンク色のマーカーとして表示されます。
マネージアロケーションは「Timeline」ビューにピンク色のマーカーとして表示されます。

割り当てコールスタック

割り当てコールスタックは、コード内のマネージメモリ割り当てを発見するための迅速な方法を提供します。これにより、通常の深いプロファイリングが追加するよりも少ないオーバーヘッドで必要なコールスタックの詳細が提供され、標準プロファイラーを使用して即座に有効にできます。

プロファイラーでは、割り当てコールスタックはデフォルトで無効になっています。それを有効にするには、プロファイラーウィンドウのメインツールバーにあるコールスタックボタンをクリックします。詳細ビューを関連データに変更します。

注:Unityの古いバージョン(割り当てコールスタックサポート以前)を使用している場合、ディーププロファイリングは、マネージ割り当てを見つけるためにフルコールスタックを取得する良い方法です。

ヒエラルキーまたは生ヒエラルキーで選択されたGC.Allocサンプルには、コールスタックが含まれるようになります。タイムラインの選択ツールチップでもGC.Allocサンプルのコールスタックを見ることができます。

プロファイラーで割り当てコールスタックを有効にすると、マネージ割り当てのソースまでコールスタックをさかのぼることができます。
プロファイラーで割り当てコールスタックを有効にすると、マネージ割り当てのソースまでコールスタックをさかのぼることができます。

CPU Usage Profiler の「Hierarchy」ビュー

CPU使用量プロファイラーのヒエラルキービューでは、列ヘッダーをクリックしてソート基準として使用できます。GCアロケーションでソートすることは、それに焦点を当てる素晴らしい方法です。

CPU Usage Profiler モジュールの「Hierarchy」ビューを使用すると、マネージ割り当てをフィルターで絞り込んで集中して処理できるので便利です。
CPU Usage Profiler モジュールの「Hierarchy」ビューを使用すると、マネージ割り当てをフィルターで絞り込んで集中して処理できるので便利です。

プロジェクト監査ツール

Unity 6.1でパッケージとして導入されたプロジェクト監査ツールは、Unityプロジェクトのための強力な分析ツールで、開発者がパフォーマンスを最適化し、ベストプラクティスを維持し、プロジェクト内の潜在的な問題やボトルネックを特定するのを助けるために設計されています。

プロジェクト監査ツールは、プロジェクト全体をスキャンし、重いスクリプト呼び出し、未使用のアセット、過剰なエンティティ数などの非効率性に関する詳細なレポートを提供します。

プロジェクト監査ツールは、いくつかの異なる領域をカバーしています:

パフォーマンス最適化:過剰なガーベジ生成、不必要なオブジェクト割り当て、高コストの関数呼び出しなど、プロジェクトのランタイムパフォーマンスに影響を与える可能性のある問題を特定します。

コードとアセットのレビュー:未使用のアセット、非効率的なコードパターン、またはリファクタリング可能な古いAPIを強調表示します。これにより、ビルドサイズを削減し、全体的なプロジェクトの保守性を向上させ、メモリ使用を最適化します。

診断とベストプラクティス:Unityのベストプラクティスに基づいた推奨事項を提供し、欠落した参照や最適でないプレイヤーまたは品質設定など、プロジェクト設定に関連するエラーや警告を強調表示します。

カスタマイズ可能なレポート:結果をカテゴリに整理し、最適化の優先順位を付けやすくします。プロジェクトやニーズに合わせて分析をカスタマイズするためのルールを作成することもできます。

💡ヒント:

- 開発の重要な段階(例:マイルストーンの前、ベータリリース、最終ビルド)でプロジェクト監査を実行します。定期的な監査は、パフォーマンスのボトルネック、未使用のアセット、または古いコードを早期に発見し、プロジェクトがスケールするにつれて問題が大きくなるのを防ぎます。

- CIやビルド設定の一部としてプロジェクト監査を自動化することができ(マニュアルのこちらに示されているように)、レポートを使用して誰も新しい問題を追加するアセットやコードをチェックインしないようにします(こちらで詳述されているAPIを使用)。

- ゲーム内で確実にキャッチしたい特定のことがある場合は、自分のルールを追加できます。例えば、テクスチャ設定、サイズ、またはより複雑なルールなどです。これを行う方法の詳細については、マニュアルのこのページを参照してください。

プロジェクト監査によって生成されたレポートは、重大度(重大、中程度、情報)によって分類されます。最も重大な問題に最初に焦点を当ててください。これらはしばしば、メモリの過剰割り当てや過剰なガベージコレクションなど、パフォーマンスに重要な問題を強調します。これらは、Updateのように頻繁に呼び出されるコードパスに存在する可能性が高く、持ち込むパフォーマンスの問題はプレイヤーにとってより明白になります。

プロジェクト監査は、プレイヤー設定品質設定などの設定もチェックし、変更すべきことについての推奨を行います。これを使用して、ビルドターゲット、解像度、テキスト圧縮、または他のプロジェクト設定が意図したプラットフォームに最適化されていることを確認します。

ドメインリロード

Unityエディターでは、プレイモードに入る際の設定を構成できます。このページには詳細が記載されていますが、ドメインリロードを無効にすることでエディターの反復時間を短縮できることがよくあります。ただし、これによりプレイモードに入るたびにスクリプトの状態がリセットされなくなるため、コード内で手動で行う必要があります。

プロジェクト監査のコードエリアは、プロジェクト内のスクリプトを分析して、スクリプト変数をリセットする必要がある場所を見つけるのに役立ちます。ドメインリロードビューに表示されるすべての問題を修正し、その後ドメインリロードを無効にすることがベストプラクティスと見なされています。このビューにデータを入力するには、PreferencesウィンドウでRoslynアナライザーの使用設定を有効にする必要があります。その後、マニュアルの指示に従って問題のリストを確認し、修正します。すべての問題が解決されたら、プレイモードに入るときにドメインリロードを無効にできます。

プロジェクト監査人の要約ビュー
プロジェクト監査人の要約ビュー

メモリと GC の最適化

UnityはBoehm-Demers-Weiserガベージコレクタを使用して、アプリケーションに必要なくなったメモリを自動的にクリーンアップします。GCはプログラムコードの実行を停止し、その作業が完了するまで通常の実行を再開しません。

自動管理は便利ですが、不必要または頻繁な割り当てはパフォーマンスの問題を引き起こす可能性があります。なぜなら、ガベージコレクタが未使用のメモリをクリーンアップするためにゲームを一時停止しなければならないからです(これをGCスパイクとも呼びます)。注意すべき一般的な落とし穴は次のとおりです:

文字列:C#では、文字列は参照型であり、値型ではありません。これは、新しい文字列がすべてマネージヒープに割り当てられることを意味します。たとえ一時的にしか使用されなくてもです。不必要な文字列の作成や操作を減らしてください。JSONやXMLなどの文字列ベースのデータファイルの解析を避け、データをScriptableObjectsやMessagePack、Protobufなどの形式に保存してください。ランタイムで文字列を構築する必要がある場合は、StringBuilderクラスを使用してください。

Unity関数呼び出し:一部のUnity API関数は、特に一時的なマネージオブジェクトの配列を返すものは、ヒープ割り当てを作成します。ループの途中で配列を割り当てるのではなく、配列への参照をキャッシュしてください。また、ガベージを生成しない特定の関数を利用してください。例えば、GameObject.CompareTagを使用して、GameObject.tagと文字列を手動で比較するのではなく、(新しい文字列を返すとガベージが生成されるため)使用してください。

プロジェクト監査人を使用してこれらの代替手段をリストアップすることもできます。これにより、可能な限り非割り当てバージョンを使用していることを確認できます。

ボクシング:ボクシングは、値型(例:int、float、struct)が参照型(例:object)に変換されるときに発生します。値型の変数を参照型の変数の代わりに渡すことは避けてください。これにより、一時的なオブジェクトが作成され、それに伴う潜在的なガベージが値型を型オブジェクトに暗示的に変換します(例:int i = 123; object o = i)。代わりに、渡したい値型で具体的なオーバーライドを提供するようにしてください。ジェネリクスはこれらのオーバーライドにも使用できます。

コルーチン:yieldはガベージを生成しませんが、新しいWaitForSecondsオブジェクトを作成するとガベージが発生します。WaitForSecondsオブジェクトをキャッシュして再利用し、yield行で新しく作成しないようにします。

LINQと正規表現:これらの両方は、裏でボクシングからガベージを生成します。パフォーマンスが問題であれば、LINQと正規表現を避けてください。forループを書き、新しい配列を作成する代わりにリストを使用してください。

ジェネリックコレクションと他の管理型:Update内で毎フレームListやコレクションを宣言してpopulateしないでください(例えば、プレイヤーの特定の半径内の敵のリスト)。代わりに、ListをMonoBehaviourのメンバーにし、Startで初期化します。使用する前に、毎フレームClearでコレクションを単純に空にします。

可能な限り時間のガベージコレクションを使用する

特定のゲームのポイントにガベージコレクションのフリーズが影響しないと確信している場合は、System.GC.Collectでガベージコレクションをトリガーできます。これの古典的な例は、ユーザーがメニューにいるかゲームを一時停止しているときで、目立たないでしょう。

これを有利に活用する方法の例については、自動メモリ管理の理解を参照してください。

インクリメンタルガベージコレクタを使用してGCの負荷を分割する

プログラムの実行中に単一の長い中断を作成するのではなく、インクリメンタルガベージコレクションは、負荷を多くのフレームに分散させる複数の短い中断を使用します。ガベージコレクションが不規則なフレームレートを引き起こしている場合は、このオプションを試して、GCスパイクの問題が軽減されるかどうかを確認してください。Profile Analyzerを使用して、アプリケーションへの利点を確認してください。

インクリメンタルモードでGCを使用すると、一部のC#呼び出しに読み書きバリアが追加され、スクリプト呼び出しのオーバーヘッドが約1msに達することがあります。最適なパフォーマンスを得るためには、メインゲームプレイループにGCアロケーションがないことが理想的です。これにより、スムーズなフレームレートのためにインクリメンタルGCを必要とせず、ユーザーが気づかない場所でGC.Collectを隠すことができます。例えば、メニューを開くときや新しいレベルを読み込むときです。そのような最適化されたシナリオでは、フルで非インクリメンタルなガベージコレクションを実行できます(System.GC.Collect()を使用)。

Memory Profilerについて詳しく学ぶには、以下のリソースをチェックしてください:

メモリプロファイラーのウォークスルーとチュートリアル

メモリプロファイラーのドキュメント

Unityのメモリプロファイラーでメモリ使用量を改善する

メモリプロファイラー:メモリ関連の問題をトラブルシューティングするためのツール

メモリプロファイラーを使った作業

コールアウトが切り取られました
Unity 6のためのさらなるヒント

Unityのベストプラクティスハブから、上級Unity開発者やクリエイター向けの多くのベストプラクティスやヒントを見つけることができます。業界の専門家やUnityのエンジニア、テクニカルアーティストが作成した30以上のガイドから選択し、Unityのツールセットやシステムを効率的に開発するのに役立ててください。