• ゲーム
  • Industry
  • リソース
  • コミュニティ
  • 学習
  • サポート
開発
Unityエンジン
任意のプラットフォーム向けに2Dおよび3Dゲームを構築
ダウンロードプランと価格
収益化
アプリ内課金(IAP)
ストア全体でIAPを発見し、管理する
Mediation
収益を最大化し、マネタイズを最適化する
Ad Quality
アプリのユーザーエクスペリエンスを保護する
Tapjoy
長期的なユーザーの忠誠心を構築する
すべてのマネタイズ製品
詳しく見る
詳しく見る
発見され、モバイルユーザーを獲得する
UnityベクターAI
プレイヤーを適切なゲームに接続する
Auraのオンデバイス広告
ピークエンゲージメント時にデバイス上のユーザーにリーチする
すべての成長製品
活用事例
3Dコラボレーション
リアルタイムで3Dプロジェクトを構築およびレビューする
没入型トレーニング
没入型環境でのトレーニング
顧客体験
インタラクティブな3D体験を作成する
すべての業界ソリューション
業界
製造業
運用の卓越性を達成する
小売
店内体験をオンライン体験に変換する
自動車
革新と車内体験を高める
全業界
技術ライブラリ
ドキュメント
公式ユーザーマニュアルとAPIリファレンス
開発者ツール
リリースバージョンと問題追跡
ロードマップ
今後の機能をレビューする
用語集
技術用語のライブラリ
インサイト
ケーススタディ
実際の成功事例
ベストプラクティスガイド
専門家のヒントとコツ
すべてのリソース
新機能
ブログ
更新情報、情報、技術的ヒント
お知らせ
ニュース、ストーリー、プレスセンター
コミュニティハブ
ディスカッション
議論、問題解決、つながる
イベント
グローバルおよびローカルイベント
コミュニティストーリー
Made with Unity
Unityクリエイターの紹介
ライブストリーム
開発者、クリエイター、インサイダーに参加する
Unity Awards
世界中のUnityクリエイターを祝う
すべてのレベルに対応
Unity Learn
無料でUnityスキルをマスターする
プロフェッショナルトレーニング
Unityトレーナーでチームをレベルアップ
Unity初心者向け
スタートガイド
学習を開始しましょう
Unityエッセンシャルパスウェイ
Unity は初めてですか?旅を始めましょう
ハウツーガイド
実用的なヒントとベストプラクティス
教育
学生向け
キャリアをスタートさせる
教育者向け
教育を大幅に強化
教育機関向けライセンス
Unityの力をあなたの機関に持ち込む
認定教材
Unityのマスタリーを証明する
サポートオプション
ヘルプを得る
Unityで成功するためのサポート
Success Plan
専門的なサポートで目標を早く達成する
FAQ
よくある質問への回答
お問い合わせ
私たちのチームに連絡する
プランと価格
言語設定
  • English
  • Deutsch
  • 日本語
  • Français
  • Português
  • 中文
  • Español
  • Русский
  • 한국어
ソーシャル
通貨
購入
  • プロダクト
  • Unity Ads
  • サブスクリプション
  • Unity Asset Store
  • リセラー
教育
  • 学生
  • 教育関係者
  • 教育機関
  • 認定資格試験
  • 学ぶ
  • スキル開発プログラム
ダウンロード
  • Unity Hub
  • ダウンロードアーカイブ
  • ベータプログラム
Unity Labs
  • ラボ
  • 研究論文
リソース
  • Learn プラットフォーム
  • コミュニティ
  • ドキュメント
  • Unity QA
  • FAQ
  • サービスのステータス
  • ケーススタディ
  • Made with Unity
Unity
  • 当社について
  • ニュースレター
  • ブログ
  • イベント
  • キャリア
  • ヘルプ
  • プレス
  • パートナー
  • 投資家
  • アフィリエイト
  • セキュリティ
  • ソーシャルインパクト
  • インクルージョンとダイバーシティ
  • お問い合わせ
Copyright © 2025 Unity Technologies
  • 法規事項
  • プライバシーポリシー
  • クッキーについて
  • 私の個人情報を販売または共有しないでください

「Unity」の名称、Unity のロゴ、およびその他の Unity の商標は、米国およびその他の国における Unity Technologies またはその関係会社の商標または登録商標です(詳しくはこちら)。その他の名称またはブランドは該当する所有者の商標です。

Hero background image

Unity でのメモリプロファイリング

このウェブページは、お客様の便宜のために機械翻訳されたものです。翻訳されたコンテンツの正確性や信頼性は保証いたしかねます。翻訳されたコンテンツの正確性について疑問をお持ちの場合は、ウェブページの公式な英語版をご覧ください。
ここをクリックしてください。

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

このページでは、Unity のアプリケーションのメモリ使用状況を分析するための 2 つのツール、ビルトイン Memory Profiler モジュールと、プロジェクトに追加できる Memory Profiler パッケージについて説明します。

この情報は、無料でダウンロードできるeBook「Ultimate guide to profiling Unity games」 から抜粋したものです。このeブックは、ゲーム開発、プロファイリング、最適化のUnity外部と内部の両方のエキスパートによって作成されました。

この記事では、Unity でのメモリプロプロファイリングについて説明します。

  • メモリプロファイリング
  • メモリバジェットを把握して定義する
  • 最小の RAM 仕様を決定する
  • 大規模なチームの場合はチームごとの予算を検討する
  • Memory Profiler モジュールの 2 種類のビュー
  • メモリプロファイラーの詳細ビュー
  • Memory Profiler のパッケージ
  • Single と Compare のスナップショットビュー
  • サマリービュー
  • グラフィカルツリーマップ
  • 樹木マップ:フィルタリングされたテーブル

メモリプロファイリング

メモリープロファイリングは、ハードウェアプラットフォームのメモリー制限に対するテスト、読み込み時間やクラッシュの削減、古いデバイスとの互換性のあるプロジェクトの作成に役立ちます。また、メモリ使用量を実際に増加させる変更を加えることで CPU/GPU のパフォーマンスを改善したい場合にも関連します。ランタイムパフォーマンスとはほとんど関係ありません。

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

Memory Profiler モジュール:これは、アプリケーションがどこでメモリを使用するかに関する基本的な情報を提供するビルトインのプロファイラーモジュールです。

Memory Profiler パッケージ:これは、プロジェクトに追加できる Unity パッケージです。Unity エディターに Memory Profiler ウィンドウが追加され、これを使用してアプリケーションのメモリー使用状況をさらに詳細に分析できます。スナップショットを保管して比較することでメモリリークを見つけたり、メモリレイアウトを確認してメモリの断片化の問題を見つけたりできます。

これらのビルトイン使用すると、メモリ使用量を監視し、アプリケーション内でメモリ使用量が予想以上に多い領域を特定し、メモリ断片化を見つけて改善できます。

メモリバジェットを把握して定義する
HARDWARE RESOURCES は、スナップショットがキャプチャされた時点におけるデバイスの RAM と VRAM の数値を表示しています。

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

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

デバイス メモリの仕様は開発者ドキュメントに記載されています。例えば、ドキュメントによると、Xbox Oneコンソールの最大使用可能メモリは、フォアグラウンドで実行されているゲームでは5 GBに制限されています。

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

物理 RAM の制限を判断する

各ターゲットプラットプラットフォームにはメモリ制限があり、それを知っていれば、アプリケーションのメモリバジェットを設定できます。Memory Profilerを使用してキャプチャショットを確認します。Hardware Resources(上の画像を参照)には、Physical Random Access Memory(RAM; 物理ランダム アクセス メモリ)と Video Random Access Memory(VRAM; ビデオ ランダム アクセス メモリ)のサイズが示されています。この数字は、そのスペースのすべてを使用できるわけではないことをアカウントしていません。ただし、作業を開始するのに便利な球面図が用意されています。

こちらに表示されている数値は、必ずしも全体像を示しているとは限らないため、ターゲットプラットフォームのハードウェア仕様をクロスリファレンスすることをお勧めします。開発者者キットのハードウェアにはより多くのメモリが搭載されている場合もあれば、統一されたメモリアーアーキテクチャを持つハードウェアを使用している場合もあります。

最小の RAM 仕様を決定する

サポートする各プラットフォームの RAM スペックが最も低いハードウェアを特定し、メモリバジェットの決定の参考にしてください。物理メモリがすべて使用できるわけではないことに注意してください。例えば、コンソールでハイパーバイザーを実行して、総メモリの一部を使用する可能性がある古いゲームをサポートできます。使用する割合(全体の 80% など)を考えます。また、モバイルプラットフォームでは、ハイエンドデバイス向けの品質と機能を向上さサポートために、複数の仕様階層に分割することを検討することもできます。

大規模なチームの場合はチームごとの予算を検討する

メモリバジェットを定義したら、チームごとのメモリ予算の設定を検討します。例えば、環境アーティストはロードされる各レベルやシーンに対して一定のメモリを使用し、オーディオチームは音楽やサウンドエフェクトに対してメモリ割り当てを行います。

プロジェクトの進捗に合わせて予算を柔軟に設定することも重要です。あるチームがバジェット内で作業を開始した場合、余剰人員を別のチームに割り当てて、開発中のゲームの領域を改善できるようにします。

ターゲットプラットフォームのメモリ予算を決定して設定したら、次のステップはプロファイリングツールを使用してゲーム内のメモリ使用量を監視および追跡することです。

Memory Profiler モジュールの 2 種類のビュー
MEMORY PROFILER モジュールを使用すると、アセットとシーンオブジェクトのメモリ割り当てに関する情報がすぐにわかります。

Memory Profiler モジュールの 2 種類のビュー

Memory Profiler モジュールには、次の 2 つのビューがあります。シンプルかつ詳細。シンプルビューを使用すると、アプリケーションのメモリー使用状況を概要ビューで確認できます。必要に応じて、詳細ビューに切り替えてさらにドリルダウンします。

シンプル

[Total Reserved Memory]の数値は、[Total Tracked by Unity Memory]です。Unity が予約しているものの、現在使用していないメモリも含まれます(この数値は Total Used Memory です)。

System Used Memory の数値は、OS がアプリケーションで使用されていると見なした値です。この数値が 0 になった場合は、プロファイリング対象のプラットフォームにプロファイラーカウンターが実装されていないことに注意してください。この場合、信頼できる最適な指標は Total Reserved Memory です。このような場合は、詳細なメモリ情報を得るためにネイティブ プラットフォーム プロファイリング ツールに切り替えることも推奨されます。

メモリプロファイラーの詳細ビュー
キャプチャしたサンプルを使用して、実行ファイルや DLL メモリの使用量などの詳細情報を確認します。

メモリプロファイラーの詳細ビュー

実行ファイル、DLL、および Mono Virtual Machine が使用するメモリの量を調べると、フレーム単位のメモリ量では足りないことがわかります。詳細なスナップショットキャプチャを使用して、このようなメモリの内訳を掘り下げます。

注:Memory Profiler モジュールの詳細ビューの参照樹木には、ネイティブ参照のみが表示されます。UnityEngine.Object を継承するタイプのオブジェクトからの参照は、そのマネージシェルの名前と一緒に表示されることがあります。ただし、これらのオブジェクトが表示されるのは、その下にネイティブオブジェクトがあるからです。マネージタイプが表示されるとは限りません。例として、Texture2Din フィールドの 1 つを参照しているオブジェクトを見てみましょう。このビューを使用すると、その参照を保持するフィールドも見えなくなります。このような詳細については、Memory Profiler パッケージを使用してください。

メモリ使用量がプラットフォーム予算に近づいてくるタイミングを大まかに判断するには、次の「ナプキンの裏」計算を使用します。

システム使用メモリ(システム使用メモリが 0 を示している場合は予約済みメモリの合計)+ トラッキングされていないメモリのボールパーク バッファ/プラットフォームの合計メモリ

この数値がプラットフォームのメモリバジェットの 100% に近づいてきたら、Memory Profiler パッケージを使用してその理由を確認してください。

Memory Profiler モジュールの多くの機能は Memory Profiler パッケージに置き換えられましたが、引き続きモジュールを使用してメモリ分析作業を補完できます。

例:

  • GC 割り当てを特定する:これらはモジュールに表示されますが、Project Auditor またはディーププロファイリングを使用すると追跡が容易です。
  • ヒープの使用済み/予約済みサイズを簡単に確認する
  • シェーダーメモリ分析

メモリバジェットを設定する際には、ターゲットプラットプラットフォーム全体のスペックが最も低いデバイスでプロファイリングを行うことを忘れないでください。メモリ使用量を厳密に監視し、目標値に注意してください。

通常は、メモリ容量が大きい強力な開発者者システムを使用してプロファイリングを行います(大容量メモリのスナップショットを保存したり、それらのスナップショットショットを迅速にロードおよび保存するためのスペースが重要です)。

メモリプロプロファイリングは、CPU や GPU のプロファイリングとは異なり、追加のメモリオーバーヘッドが発生する可能性があります。(より多くのメモリを搭載した)ハイエンド デバイスでメモリのプロファイリングが必要になる場合もありますが、特にローエンドのターゲット仕様ではメモリ バジェット制限に注意してください。

メモリ使用量のプロファイリング時に考慮すべき点:

  • 品質レベル、グラフィックスのティア、アセットバンドルのバリアントなどの設定は、より強力なデバイスではメモリ使用量が異なる場合があります。例:
  • 品質レベルとグラフィックスの設定は、シャドウマップに使用されるレンダーテクスチャのサイズに影響を与える可能性があります。
  • 解像度スケーリングは、画面バッファ、RenderTexture、およびポストプロセスエフェクトのサイズに影響を与える可能性があります。
  • テクスチャ品質の設定がすべてのテクスチャのサイズに影響を与える可能性があります。
  • 最大 LOD はモデルなどに影響を与える可能性があります。
  • HD(HD)バージョンやSD(標準定義)バージョンなどのアセットバンドルバリアントがあり、デバイス仕様に基づいて使用するものを選択すると、プロファイリングするデバイスによってアセットサイズも異なる場合があります。
  • ターゲットデバイスの画面解像度は、ポストプロセスエフェクトに使用されるレンダーテクスチャのサイズに影響します。
  • デバイスでサポートされているグラフィックス API は、API でサポートされているバリアントまたはサポートされていないバリアントに基づいて、シェーダーのサイズに影響を与える可能性があります。
  • 異なる品質設定、グラフィックティア設定、およびアセットバンドルのバリエーションを使用する階層型システムがあれば、例えば、4 GB のモバイルデバイスに HD 定義バージョンのアセットバンドルをロードし、2 GB のデバイスに標準定義バージョンをロードするなど、より広い範囲のデバイスをターゲットにするのに役立ちます。ただし、上記のメモリ使用量の変動を考慮して、両方のタイプのデバイスと、画面解像度やサポートされているグラフィックス API が異なるデバイスをテストしてください。

注:Unity エディターは、通常、エディターとプロファイラーから読み込まれるオブジェクトが増えるため、常にメモリフットプリントが大きくなります。また、アセットバンドル (Addressables シミュレーションモードによる) やスプライトとアトラス、Inspector に表示されるアセットなど、ビルドのメモリにロードされないアセットメモリが表示されることもあります。また、参照チェーンの中には、エディター内で混乱を招くものもあるかもしれません。

Memory Profiler のパッケージ
MEMORY PROFILER のウィンドウビュー

Memory Profiler のパッケージ

Memory Profilerは現在、Unity 2019 LTS以降でプレビュー版ですが、Unity 2022 LTSで検証される予定です。

Memory Profiler パッケージの大きな利点の 1 つは、(Memory Profiler モジュールのように) ネイティブオブジェクトをキャプチャするだけでなく、マネージメモリをビューし、スナップショットを保存および比較して、メモリ使用量の内訳を視覚的に表示して、メモリの内容をさらに詳しく探ることができることです。

エンジン内のメモリ割り当てがスナップショットに表示されるため、過剰または不要なメモリ使用の原因をすばやく特定したり、メモリリークを追跡したり、ヒープ断片化を確認したりすることができます。

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

Memory Profiler の上部のメニューでは、プレイヤー選択ターゲットを変更したり、スナップショットショットをキャプチャまたはインポートしたりできます。

注:「Target selection」ドロップダウンで Memory Profiler をリモートデバイスに接続して、ターゲットハードウェアのメモリをプロファイリングします。Unity エディターでのプロファイリングでは、エディターやその他のツールによって追加されたオーバーヘッドにより、不正確な数値が表示されます。

Single と Compare のスナップショットビュー
ワークベンチペインはメモリスナップショットの管理に使用します。

Single と Compare のスナップショットビュー

Memory Profiler ウィンドウの左側に Workbench 領域があります。これを使用して、保存されたスナップショットを管理したり開いたり閉じたりできます。また、この領域を使用して、単一スナップショットとスナップショットの比較ビューを切り替えることもできます。

Profile Analyzer と同様に、Memory Profilerでは 2 つのデータ(メモリスナップスナップショット)をロードして比較できます。これは特に、時間の経過やシーン間のメモリ使用量の増加を確認したり、メモリリークを検索したりする場合に便利です。

Memory Profiler のウィンドウには、Summary、Objects and Allocations、Fragmentation などのスナップショットを掘り下げるタブが多数あります。それぞれのオプションを詳しく見ていきましょう。

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

サマリービュー

このビューは、プロジェクトのメモリー使用状況を簡単に確認したいときに選択します。また、問題となっているキャプチャされたメモリスナップショットのメモリ関連の有用かつ重要な数値も含まれています。スナップショットが撮影された時点で何が起きているかを簡単に確認するのに最適です。

グラフィカルツリーマップ
サマリービューには、そのスナップショットがキャプチャされた時間のメモリ使用量の樹木マップも表示されます。

グラフィカルツリーマップ

樹木マップビューには、オブジェクトが使用しているメモリの内訳がグラフィカルな樹木マップとして表示されます。このツリーマップを詳しく調べると、最もメモリを消費するオブジェクトの種類を見つけることができます。

樹木マップ:フィルタリングされたテーブル

樹木マップ:フィルタリングされたテーブル

樹木マップビューの下には、選択したグリッド内のオブジェクトのリストをディスプレイするように更新される、フィルタリングされたテーブルがあります。

樹木マップには、オブジェクト(ネイティブまたはマネージ)に起因するメモリが表示されます。マネージ オブジェクト メモリはネイティブ オブジェクト メモリよりも小さくなる傾向があり、マップ ビューで見つけるのが難しくなります。樹木マップをズームして見ることができますが、小さなオブジェクトを調べる場合は、通常、表のほうが概要がわかりやすいでしょう。樹木マップ内のセルをクリックすると、その下の表がセクションのタイプにフィルターされるか、表内の特定のオブジェクトが選択されます。

このリスト内のどのアイテムがオブジェクトを参照しているか、およびこれらの参照がどのマネージクラスフィールドに存在するかを追跡するには、テーブル行はそれを表す樹木マップグリッドセルを選択し、「Details」サイドパネルの「References」セクションをチェックします。側面が非表示になっている場合は、ウィンドウの右上にあるボタンできます。

注:樹木マップには、メモリ内のオブジェクトのみが表示されます。これは追跡されたメモリを完全に表現したものではありません。これは、「Memory Usage Overview」の数値が「Tracked Memory」の合計と同じではないことに気付いた場合に備えて、理解しておくことが重要です。

これは、すべてのネイティブブメモリがオブジェクトに結び付けられているわけではないためです。また、実行可能ファイルや DLL、NativeArray など、オブジェクトに関連付けられていないネイティブ割り当てで構成することもできます。「予約済みだが未使用のメモリ領域」など、さらに抽象的な概念は、ネイティブ割り当ての合計にも適用できます。

  • Objects and Allocations
  • メモリプロプロファイリング手法とワークフロー
  • メモリリークの特定
  • アプリケーション生存期間にわたって繰り返し発生するメモリ割り当ての特定
  • メモリ割り当ての特定
  • 「CPU Usage Profiler」モジュールの「Timeline」ビュー
  • 割り当てコールスタック
  • CPU Usage Profiler の「Hierarchy」ビュー
  • プロジェクト監査人
  • メモリと GC の最適化
Objects and Allocations
「OBJECTS AND ALLOCATIONS」テーブルは多くのレベルでフィルターできるので、キャプチャされたスナップショットのメモリ使用量を高い粒度で掘り下げることができます。

Objects and Allocations

オブジェクトと割り当てビューには、すべてのオブジェクト、すべてのネイティブ オブジェクト、すべてのマネージ オブジェクト、すべてのネイティブ割り当てなど、既製の選択に基づいてフィルターに切り替えることができる表が表示されます。

下の表を切り替えると、選択した範囲内のオブジェクト、割り当て、またはメモリ領域をディスプレイできます。樹木マップビューで述べたように、すべてのメモリがオブジェクトに紐付けられているわけではないため、「All Memory Regions」ページと「All ネイティブ Allocations」ページでは、メモリ使用量をより詳細に把握することができます。「Memory Regions」ページには、予約されているが現在使用されていないメモリも含まれます。

メモリ使用量を最適化したり、メモリ予算が限られているハードウェアプラットフォーム向けにメモリをより効率的にパッキングしたりする場合に、この方法をご活用ください。

メモリプロプロファイリング手法とワークフロー

Memory Profilerのスナップショットをロードし、樹木マップビューでメモリフットプリントのサイズが大きいものから小さいものへとカテゴリを確認します。

プロジェクトアセットは、メモリ消費量が最も多いことが多いです。Table ビューを使用して、テクスチャチャオブジェクト、メッシュ、オーディオクリップ、レンダーテクスチャ、シェーダー、および事前に割り当てられたバッファを探します。これらはすべて、メモリ最適化の良い候補です。

メモリリークの特定

メモリリークは一般的に以下の場合に発生します。

  • コードを通じてオブジェクトがメモリから手動で解放されない
  • オブジェクトが意図しない参照のためにメモリに残っている

Memory Profiler Compare モードは、特定の期間における 2 つのスナップショットショットを比較することで、メモリリークを見つけるのにヘルプます。

Unity ゲームでよく見られるメモリリークのシナリオは、シーンをアンロードした後に発生することがあります。

Memory Profiler パッケージには、Compare モードを使用してこの種のリークを検出するプロセスをガイドするワークフローがあります。

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

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

次の節では、プロジェクトでマネージヒープ割り当てを特定するのに役立つヒントをいくつかリストします。

メモリ割り当ての特定
GC ALLOCATED IN FRAME に見られるスパイクにより、マネージ割り当てを調査するためのポインターが与えられます。

メモリ割り当ての特定

Unity プロファイラーの Memory Profiler モジュールは、フレームごとのマネージ割り当てを赤い線で表します。ほとんどの場合、この値は 0 である必要があるため、この行のスパイクはマネージ割り当てを調査する必要があるフレームを示しています。

「CPU Usage Profiler」モジュールの「Timeline」ビュー
マネージ割り当ては「TIMELINE」ビューにピンク色のマーカーとして表示されます。

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

CPU 使用状況プロファイラーモジュールの Timeline ビューには、マネージ割り当てを含む割り当てがピンク色で表示され、見やすく、詳細に確認できます。

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

割り当てコールスタック

割り当て呼び出しスタックは、コード内のマネージメモリ割り当てを簡単に検出する方法を提供します。これらは、ディーププロファイリングが通常追加するよりも少ないオーバーヘッドで必要なコールスタックの詳細を提供し、標準のプロファイラーを使用してその場で有効にすることができます。

割り当て呼び出しスタックは、プロファイラーではデフォルトで無効になっています。これらを有効にするには、「プロファイラー」ウィンドウのメインツールバーで「Call Stacks」ボタンをクリックします。「Details」ビューを関連データに変更します。

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

「Hierarchy」または「Raw Hierarchy」で選択した GC.Alloc サンプルに、その呼び出しスタックが含まれるようになります。Timeline の選択ツールチップで GC.Alloc サンプルの呼び出しスタックを確認することもできます。

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

CPU Usage Profiler の「Hierarchy」ビュー

CPU 使用率プロファイラーの階層ビューでは、列ヘッダーをクリックしてソート基準として使用できます。GC Alloc でソートすることは、それらに焦点を当てるのに最適な方法です。

プロジェクト監査人

Project Auditor は実験的な静的分析ツールです。このガイドでは取り上げない便利な機能も多くありますが、マネージ割り当ての原因となるプロジェクト内のすべてのコード行のリストを、プロジェクトを実行することなく生成できます。この種の問題を発見して調査するのに非常に効率的な方法です。

メモリと GC の最適化

Unity は Boehm-Demers-Weiser ガベージ コレクターを使用します。これは、プログラム コードの実行を停止し、作業が完了した場合にのみ通常の実行を再開します。

GC スパイクの原因となる不要なヒープ割り当てに注意してください。

  • 文字列:C# では、文字列は値型ではなく参照型です。つまり、新しい文字列は、たとえ一時的にしか使用されていない場合でも、すべてマネージヒープに割り当てられます。不要な文字列作成や操作を減らします。JSONやXMLなどの文字列ベースのデータファイルの解析は避け、代わりにScriptableObjectまたはMessagePackやProtobufなどの形式でデータを保存してください。ランタイム時に文字列をビルドする必要がある場合は、StringBuilder クラスを使用します。
  • Unity 関数呼び出し:Unity API 関数の中には、特にマネージオブジェクトの配列を返すようなヒープ割り当てを作成するものがあります。ループの途中で割り当てるのではなく、配列への参照をキャッシュする。また、ガベージを発生させない特定の関数も活用しましょう。例えば、 ゲームオブジェクト.tag と文字列を手動で比較するのではなく、 ゲームオブジェクト.CompareTag を使用します(新しい文字列を返すとガベージが発生するため)。
  • ボクシング:参照型変数の代わりに値型変数を渡すことは避けてください。これにより一時オブジェクトが作成され、それに伴うガベージの可能性により、値型が暗示的に型オブジェクトに変換されます (例: int i = 123; オブジェクト o = i)。代わりに、渡したい値型で具体的なオーバーライドを提供するようにしましょう。これらのオーバーライドにはジェネリックも使用できます。
  • コルーチン: yield はガベージを発生させませんが、新しい WaitForSeconds オブジェクトを作成するとガベージを発生させます。WaitForSeconds オブジェクトを yield 行で作成するのではなく、キャッシュして再利用するか、 yield return null を使用します。
  • LINQ と正規表現:これらは両方とも、バックグラウンドでボックス化によってゴミを生成します。パフォーマンスに問題がある場合は、LINQ と正規表現の使用は避けてください。for ループを記述し、新しい配列を作成する代わりにリストを使用します。
  • Generic Collections およびその他のマネージタイプ:Update で毎フレームリストやコレクションを宣言して入力しないでください (例えば、プレイヤーの一定半径内の敵のリスト)。代わりに、リストを MonoBehaviour のメンバーにして、開始時に初期化します。コレクションを使用する前に、すべてのフレームを消去してコレクションを空にします。

可能な限りガベージコレクションを行う

ガベージコレクションのフリーズがゲームの特定のポイントに影響を及ぼさないことが確実な場合は、System.GC.Collectでガベージコレクションをトリガーできます。

これをうまく活用する例については、「 自動メモリ管理について 」を参照してください。

インクリメンタルガベージコレクターを使用してGCワークロードを分割する

インクリメンタルガベージコレクションでは、プログラムの実行中に1回の長い中断を作成するのではなく、複数回の短い中断を使用して、ワークロードを多くのフレームに分散します。ガベージコレクションが原因でフレームレートが不規則になっている場合は、このオプションを試し、GCスパイクの問題を軽減できるかどうかを確認します。Profile Analyzer を使用して、アプリケーションにとってのメリットを確認します。

インクリメンタルモードで GC を使用すると、一部の C# 呼び出しに読み書きの障壁が加わり、スクリプティング呼び出しのオーバーヘッドヘッドがフレームあたり最大 1 ミリ秒増加する可能性があることに注意してください。最適なパフォーマンスを得るには、メインのゲームプレイループに GC Alloc を使用しないことが理想的です。これにより、スムーズなフレームレートのためにインクリメンタル GC が不要になり、GC を隠すことができます。例えば、メニューを開いたときや新しいレベルをロードするときなどに、ユーザーが気づかない場所で収集します。

Memory Profiler の詳細については、次のリソースを参照してください。

  • Memory Profiler ドキュメント
  • 「Unity のメモリプロファイラーでメモリ使用量を改善 する」チュートリアル
  • Memory Profiler:メモリ関連の問題をトラブルシューティングするためのツール Unite セッション
  • 『Working with the Memory Profiler Unity Learn』セッション
Unity キー 21 07
もっと色々と知りたい方には

eBook『Ultimate guide to profiling Unity games』を無料でダウンロードして、すべてのヒントとベスト プラクティスをご確認ください。

e ブックをダウンロード