Unreal Engine 5 (UE5) では、Unreal Insights の機能が拡張され、改善されたメモリトラッキングおよびプロファイリング向けのサポートが Memory Insights 機能に追加されました。 これによりデベロッパーは、任意の時点でメモリの各ブロックに関連付けられた Low Level Memory (LLM) タグやコールスタックなど、メモリの割り当てと解放に関する情報をさらに詳細に確認できるようになりました。
Memory Insights が備えるクエリ システムを利用すると、特定の時点でのライブ割り当てを見つけて、メモリ使用量の増減を確認し、短期と長期の割り当てを区別して、メモリリークを発見できます。
UE5.4 以降では、Android プロジェクトのコールスタックを使用したメモリ トレーシングがサポートされます。
セッションをレコーディングする
Memory Insights の利用を開始し、メモリ チャンネル内のトレースを記録するには、以下の手順に従います。
Unreal Insights を実行またはビルドする
[Start (スタート)] > [Command Prompt (コマンド プロンプト)] に移動し、以下を入力します。
Engine\Binaries\Win64\UnrealInsights.exeまたは、Engine\Binaries\Win64フォルダに移動し、UnrealInsights.exeをダブルクリックして実行します。
メモリ トレーシングを使用してゲーム プロジェクトを実行する
オペレーティング システムからコマンド プロンプトを起動し、プロジェクト サンプルを実行します。
cd C:\MyEngineInstallLocation\
Samples\Games\MyGameSample\Binaries\Win64\MyGameSample.exe -trace=default,memoryプロジェクトのセッションをレコーディングするには、プロセスの最初からメモリ トレース チャンネルを有効にしておく必要があります。 そうしないと、遅延接続セッションで割り当てイベントのトレースを開始できなくなります。 さらに、パッケージ化されたプロジェクトでトレースを実行している場合は、開発モードでパッケージ化されていることを確認する必要があります。
trace コマンドの metadata と assetmetadata を使用すると、アセット名およびクラス名に追加のフィルタリング オプションを提供できます。 たとえば、アセットごとやクラス名ごとにメモリ アロケーションの負荷を計算できます。
Samples\Games\MyGameSample\Binaries\Win64\MyGameSample.exe -trace=default,memory,metadata,assetmetadataInsights セッション ブラウザからトレースを開く
Unreal Insights のセッション ブラウザに戻って、.utrace をダブルクリックします。Unreal Engine の [Timing Insights (タイミング インサイト)] ウィンドウでの解析のために開きます [Menu (メニュー)] > [Memory Insights (メモリ インサイト)] を選択し、[Memory Insights (メモリ インサイト)] ウィンドウを開きます。
メモリ割り当て - グラフ トラック
Unreal Insights では、プロジェクトに割り当てられているメモリの分析を提供するために、各割り当てイベントの完全なコールスタックをキャプチャします。 Memory Insights のメイン インターフェイスには、セッション中のメモリ使用に関する概要を示すタイムラインが表示されます。
[Main Memory Graph (メイン メモリ グラフ)] には、プロジェクトで追跡したメモリの総量が表示されます。これには、 LLM から収集した各タグの情報が含まれます。 さらに、ライブ割り当ての合計数を示す次のグラフがあります。
| グラフタイプ | 色 | 説明 |
|---|---|---|
合計割り当て済みメモリ | 青 | 詳細な割り当ての追跡に基づいて、各時点で割り当てられたメモリの合計量を表示します。 |
ライブ割り当て数 | 黄 | 任意の時点でのアクティブな割り当ての総数を表示します。 |
割り当て/解放イベント数 | 緑/オレンジ | 単位あたりの割り当てイベント数および解放イベント数を示します。これは、時間の「スライス」として表されます。 |
これらの各グラフは、詳細な割り当ての追跡に基づいています。 追跡は、時間値 0 から開始され、約 1ms の詳細度があります。 LLM プレフィックス タグ (RenderTargets、SceneRender、UObject) があるその他のグラフは、Low-Level Memory トラッキング ランタイム システムに基づいています。
これらのタグは、セッションが開始して数秒してからトラッキングを開始し、フレーム単位の詳細度があります。
デフォルトでは 4096 件の割り当て / 解放イベントごとに 1 つのタイムスタンプが発行されますが、この数値は必要に応じて 「Engine/Source/Runtime/Core/Private/ProfilingDebugging/MemoryAllocationTrace.cpp」 にある MarkerSamplePeriod を修正することで変更できます。 たとえば、この変数の値を 0 に設定すると、割り当て/解放イベントが発生するごとに 1 つのタイムスタンプが発行されます。
Memory Insights のタイムラインは、[Timing View (タイミング ビュー)] へのトラックのオーバーレイをサポートしています。 Memory Insights ビューには、[Timing (タイミング)] 、[Investigation (調査)]、[LLM Tags (LLM タグ)]、および [Modules (モジュール)] の 4 つのパネルが表示されます。
タイミング ビュー
[Timing (タイミング)] をクリックして、[Timing View (タイミング ビュー)] ウィンドウの表示を切り替えることができます。 ここでは、メモリ使用率に関連するさまざまなトラックのパフォーマンス データを観察およびフィルタできます。
Investigation パネル
[Investigation (調査)] パネルでは、割り当てに関するさまざまなクエリを実行できます。
Low-Level Memory (LLM) Tags
[LLM Tags (LLM タグ)] パネルでは、さまざまな LLM タグの可視性を制御します。 このデータは、使用しているオペレーティング システムから直接トレースされます。
[LLM Tags (LLM タグ)]、アセット、およびソース ファイルをグループ化できます。 さらに、[LLM Tags (LLM タグ)] パネルにある任意の LLM タグを右クリックして [Generate a New Color (新しい色を生成)] または [Edit Color (色を編集)] を選択すると、表示される色をカスタマイズできます。
モジュール
コール スタック シンボルが解決されると、その結果がキャッシュ ファイルに格納されます。 これらのファイルは、Modules (モジュール) をクリックすると表示できます。 このパネルでは、古いトレース ファイルを開いて、シンボルを使用できます。
Discovered、Cached、Resolved、Failed の各シンボルの数の列を確認できます。 失敗したリスト アイテムが赤色で強調表示され、正しく解決されたリスト アイテムは緑色で強調表示されます。 黄色は一部のシンボルが解決され、一部が失敗したことを示しています。
以前のメモリ トラッキングのランタイムの実装は、フォルダ「Engine\Source\Runtime\Core\Public\HAL\LowLevelMemTracker.h」にある LowLevelMemTracker クラスに実装されています。 [LLM Tags] パネルと LLM グラフの両方で、このシステムから直接トレースされたデータが使用されています。 詳細な割り当てデータは、別の固有のトレースの実装から取得されます。
Memory Insights には、新しいクエリ機能と追跡されたメモリ割り当て情報が含まれます。 特定の時間枠 (ある瞬間の前後) に UE5 が割り当て/解放を行ったメモリ ブロックを特定したり、メモリリークを確認したりできます。 トレース ログを開いて [Investigation (調査)] タブに移動すると、クエリ システムにアクセスできます。
モジュールパネルの下部にあるステータス バーには、モジュールの総数とサイズに関する情報が表示されます。
[Investigation] - 割り当てのクエリ
タイムラインにメモリ使用率の概要が示されると同時に、「クエリ」を使用することで、一定の時間範囲にわたる個々の割り当ての振る舞いが評価されます。 クエリ は、 ルール と、1 つ以上のタイムスタンプ (例: ラベル A および B) で定義されます。
使用可能なクエリ ルールは次のとおりです。
| クエリ ルール | 時間変数 | 説明 |
|---|---|---|
Active Alloc (アクティブな割り当て) | A | A 時点でのアクティブな割り当てをすべて表示します。 |
前 | A | A 時点前のすべての割り当てを表示します。 |
後 | A | A 時点後のすべての割り当てを表示します。 |
Decline (減少) | A と B | A 時点前に割り当てられて、A 時点と B 時点の間に解放されたすべての割り当てを表示します。 |
Growth (増加) | A と B | A 時点と B 時点の間に割り当てられて、B 時点後に解放されたすべての割り当てを表示します。 |
Growth Vs Decline (増加と減少) | A と B | 時間 A~B の間に割り当てられた「増加」割り当て (時間 A と時間 B の間に割り当てられ、時間 B の後に解放される) と「減少」割り当て (時間 A の前に割り当てられ、時間 A と時間 B の間に解放される) の両方を特定します。 「decline」割り当ては負のサイズになるよう変更されているので、サイズの集計では A と B でバラつきがあります。 このクエリの結果は、時間 A に割り当てられた内容と時間 B に割り当てられた内容の比較になります。 タグまたはコール スタックによるメモリ割り当てのグループ化では、グループごとのバラつき (B - A) が示されます。 |
Free Events (解放イベント) | A と B | A 時点と B 時点の間に解放されたすべての割り当てを表示します。 |
Alloc Events (割り当てイベント) | A と B | A 時点と B 時点の間に割り当てられたすべての割り当てを表示します。 |
Short Living Allocs (短寿命の割り当て) | A と B | A 時点後に割り当てられて、B 時点前に解放されたすべての割り当てを表示します。 このルールは、スタック割り当ての可能性がある割り当てを特定するために使用できます。つまり、これによって一時的または短寿命の割り当てが特定されます |
Long Living Allocs (長寿命の割り当て) | A と B | A 時点前に割り当てられて、B 時点後に解放されたすべての割り当てを表示します。 |
Memory Leaks (メモリリーク) | A、B、および C | A 時点と B 時点の間に割り当てられたもので、C 時点後まで解放されていないすべての割り当てを表示します。 これは、レベルの遷移中など、特定の時点で解放される予定のメモリを特定する際に便利です。 |
Limited Lifetime (限定された存続期間) | A、B、および C | A 時点と B 時点の間に割り当てられて、B 時点と C 時点の間に解放されたすべての割り当てを表示します。 |
Decline of Long Living Allocs (長寿命の割り当ての減少) | A、B、および C | A 時点前に割り当てられて、B 時点と C 時点の間に解放されたすべての割り当てを表示します。 |
Specific Lifetime (特定の存続期間) | A、B、C、および D | A 時点と B 時点の間に割り当てられて、C 時点と D 時点の間に解放されたすべての割り当てを表示します。 |
クエリを作成するには、ルールを選択して、タイムライン内のラベル付きマーカーを目的の位置にドラッグするか、または[Investigation (調査)] タブで時間を直接指定します。
目的のルールと時間を選択したら、[Investigation (調査)] タブの [Run Query (クエリを実行)] ボタンをクリックしてクエリを実行します。
クエリとキャプチャするデータ セットによっては、クエリの実行に長時間かかる場合があります。
割り当ての詳細ビュー
クエリを実行すると新しいウィンドウが表示され、クエリが完了した際にその結果が割り当てテーブルに表示されます。 デフォルトでは、この結果はフラット リストの形式で表示されます。
デフォルトでは、各割り当ては次のように表示されます。
回数
サイズ
LLM Tag (LLM タグ)
関数 (Alloc)
割り当てコールスタック
関数 (Free)
Free コールスタック
テーブルの見出しを右クリックし、Column Visibility (列の可視性) の下で設定することで、追加のパラメータを表示できます。 さらに、割り当ての左側にある●アイコンにカーソルを合わせると、詳細情報が表示されます。
画面下部のステータス バーで、選択した割り当てに関する合計数やメモリ サイズなどの詳細を表示できます。
並び替え
テーブルのヘッダをクリックすることで、リストをさまざまな列でソートできます。
| 列のソート | 説明 |
|---|---|
Allocation Hierarchy (割り当て階層) | 割り当てツリーの階層でソートします。 |
Allocation Count (割り当て数) | 割り当て数でソートします。 |
サイズ | 割り当てサイズでソートします。 |
LLM Tag (LLM タグ) | 割り当ての LLM タグでソートします。 |
Function (Callstack) (関数 (コールスタック)) | 割り当てのコールスタックの解決済みの上位の関数でソートします。 |
CallStack Size (コールスタックのサイズ) | コールスタック フレームの数 |
グループ化
プリセット オプションを使用すると、割り当てをグループにまとめられます。
| プリセット オプション | 説明 |
|---|---|
デフォルト | デフォルトの割り当てを表示します。 |
Detailed (詳細) | ツリー ビューで割り当ての詳細情報を表示するよう設定します。 |
Heap (ヒープ) | さまざまなタイプのメモリの使用方法を調査します。 複数のアドレス空間を参照してください。 |
サイズ | 大規模な割り当てをすばやく見つけることができます。 |
タグ | 割り当てをシステム別に表示します。 |
アセット (パッケージ) | パッケージとアセット名メタデータ別のアロケーションの内訳が表示されるようにツリー ビューを設定します。 |
クラス名 | クラス名ごとの割り当ての内訳が表示されるようにツリー ビューを設定します。 |
Allocコールスタック | コールスタック別の割り当ての内訳が表示されるようにツリー ビューを設定します。 |
反転割り当てコールスタック | 反転コールスタック別に割り当ての内訳を表示するようにツリー ビューを構成します。 |
Freeコールスタック | free コールスタック別の割り当て内訳を表示するようにツリー ビューを設定します。 |
反転解放コールスタック | 反転 free コールスタック別の割り当て内訳を表示するようにツリー ビューを構成します。 |
Address(4k Page) (アドレス (4k ページ)) | 割り当てをそのアドレスに基づいて 4K アライメントのメモリ ページにグループ化します。
|
[Hierarchy (階層)] に移動して [All (すべて)] をクリックするとドロップダウン メニューが表示され、ここでデフォルトのフラット ビューから別のグループ化オプションに変更することができます。
次のオプションのリストから階層をグループ化できます。
| 階層グループ | 説明 |
|---|---|
Flat (フラット表示) | すべての項目を含む単一のグループを作成します。 |
サイズ | サイズに基づいて割り当てをグループ化します。 |
タグ | タグ階層に基づいてツリーを作成します。 |
Callstack | 各割り当てのコールスタックに基づいてツリーを作成します。 |
Inverted Callstack (反転コールスタック) | 各割り当てのコールスタックに基づいてツリーを作成します。 |
Heap (ヒープ) | ヒープに基づきツリーを作成します。 ルート ヒープでは、割り当てとヒープのサブグループを利用できます。 |
Unique Values - Event Distance (固有値 - イベント距離) | イベント距離の値ごとにグループを作成します |
Unique Values - Start Time (固有値 - 開始時間) | 開始時間の値ごとにグループを作成します |
Unique Values - End Time (固有値 - 終了時間) | 終了時間の値ごとにグループを作成します |
Unique Values - Duration (固有値 - 期間) | 期間の値ごとにグループを作成します |
Unique Values - Address (固有値 - アドレス) | 各アドレスの値ごとにグループを作成します |
Unique Values - Memory Page (固有値 - メモリ ページ) | メモリ ページの値ごとにグループを作成します。 |
Unique Values - Size (固有値 - サイズ) | サイズ値ごとにグループを作成します |
Unique Values - LLM Tag (固有値 - LLM タグ) | LLM タグ値ごとにグループを作成します |
Unique Values - Asset (固有値 - アセット) | アセット値ごとにグループを作成します |
Unique Values - Class Name (固有値 - クラス名) | クラス名の値ごとにグループを作成します |
Unique Values - Top Function (固有値 - 最上位関数) | 最上位関数の値ごとにグループを作成します |
Unique Values - Top Source File (固有値 - 最上位ソース ファイル) | 最上位ソースファイルの値ごとにグループを作成します |
Unique Values - Callstack Size (固有値 - コールスタック サイズ) | コールスタック サイズの値ごとにグループを作成します |
Path Breakdown - LLM Tag (パスのブレークダウン - LLM タグ) | LLM タグの文字列型の値の構造体からツリー階層を作成します。 |
Path Breakdown - Asset (パスのブレークダウン - アセット) | アセット タグ文字列型の値の構造からツリー階層を作成します。 |
Path Breakdown - Top Source File (パスのブレークダウン - 最上位ソース ファイル) | 最上位ソース ファイルの文字列型の値の構造体からツリー階層を作成します。 |
詳細フィルタリング
検索テキスト ボックスでは、階層ノードのテキストに基づいて結果を迅速にフィルタする方法を利用できます。 クエリによって生成された割り当てのセットは、検索テキスト ボックスの横の [Filter Configurator (フィルタ コンフィグレータ)] をクリックしてさらにフィルタを適用し、割り当てのグループを分離できます。
グループや、AND/OR キーワードを使用し、詳細なクエリを構築することもできます。
コールスタック シンボル解決
プログラム カウンター アドレスを使用することで、プロジェクトからのコールスタック シンボル トレーシングを実行できます。 解析では、対応するソース ファイルに関する情報とともに、これらのアドレスを読み取り可能な文字列に解決する必要があります。
これには、Memory Insights でデバッグ情報を含む正しいバージョンのファイルにアクセスできる必要があります。 プラットフォームに応じて .pdbまたは .elfファイルのいずれか。 Insights では、次のリストに従って正しいファイルを検索します。
このセッション中にユーザーによって入力された新しいパス。
実行可能ファイルのパス (一部のプラットフォームで利用可能な場合。これはコンパイルされてバイナリになる)。
UE_INSIGHTS_SYMBOLPATH環境変数からのパス。 この変数は、セミコロン区切りのパスを受け入れます。_NT_SYMBOL_PATHからのパス。ユーザー コンフィギュレーション ファイルからのパス。
すべてのシンボルが解決されると、その結果がキャッシュ ファイルに格納されます。 これらのファイルは、[Modules (モジュール)] パネルをクリックすると表示できます。 続いて、選択したファイルを右クリックし、ドロップダウン メニューから以下のうち 1 つを選択すると、これらのファイルを開くことができます。
これにより、トレース ファイルを他のユーザーに送信する方法が提供されます。このデバッグ情報へのアクセス権は不要です。
| ロード方法 | 説明 |
|---|---|
Load symbols from file (ファイルからシンボルをロード) | ファイルを指定して、モジュールのシンボルをロードします。 成功した場合、同じディレクトリから他の失敗したモジュールのロードを試みます。 |
Load symbols from directory (ディレクトリからシンボルをロード) | ディレクトリを指定して、モジュールのシンボルをロードします。 成功した場合、同じディレクトリから他の失敗したモジュールのロードを試みます。 |
現時点では、シンボルの解決は Win64、XB1/XSX、PS4/PS5、および Switch でサポートされています。
複数のアドレス空間
メモリ トレーシングでは、さまざまなヒープのメモリをトラックします。 概念的には、すべての割り当ては、あるタイプのメモリを表すルート ヒープに属している必要があります。 たとえばデスクトップ プラットフォームでは、あるルート ヒープがシステム メモリで、他のものがグラフィック カード上のビデオ メモリである場合があります。 それぞれのルート ヒープには独自のアドレス空間があります。 各ルート ヒープでは、割り当てのホストが可能なヒープ割り当てが作成されます。 通常、これは割り当てをバックアップする仮想メモリ割り当てを意味しますが、ヒープ割り当てでブロック スタイル アロケータを表すことも可能です。 これによって、これらのメモリ ブロックの使用に関する調査が提供されます。
スナップショットをエクスポート
メモリ割り当ては、.csv ファイルまたは .tsvファイルとしてエクスポートできます。右クリックしてコンテキスト メニューから Export Snapshot (スナップショットをエクスポート) を選択してください。