12
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Epic Games Japan #3Advent Calendar 2019

Day 21

[UE4] MemProを使用したメモリトラッキング

Last updated at Posted at 2019-12-20

1. はじめに

[検証バージョン:4.23.0]
 MemProはC++メモリトラッキングツールで、UE4は4.23からインテグレーションに対応しています。
本記事では MemPro を使用してUE4アプリケーションのメモリトラッキングを行う方法について説明します。
Summry.png

2. MemProの利用にあたって

 MemProをUE4で利用する上で、導入を検討する内容としてご参考ください。

2.1. 機能

・LLMタグベースでのメモリをトラッキングします
 (UE4でメモリトラッキング時にはLLMタグの指定が必須)
・関数別、タイプ別での追跡機能や差分の検出機能があります
・キャプチャしたデータをエクスポートできます

2.2. メリット

・イテレーションやセットアップのしやすさの点でMalloc Profilerよりも優れています1
・コールツリーの機能を持つためLLMよりもトラッキング精度の面で優れています2
・トラッキング処理のコストも比較的低く、比較的長時間のトラッキングが可能です3

2.3. 注意点

・MemProは有償のツールで、トライアルで30日間無償で利用可能、[MemPro]->[Purchase]から購入可能です
 (1マイナーバージョンアップグレードの永久ライセンス:JP¥15,390/1ユーザーライセンス)4

3. MemProで出来ること

 以下にMemProツールで出来ることを示します。予め出来ることを把握することで、メモリトラッキングの目的に合致しているかを確認しておくとより効果的です。

3.1. Memory Graph

 使用メモリ量をグラフ化して推移を確認できます。
2019-11-20_02h40_29.png

3.2. Call Tree

 メモリがAllocateされるまで経路の階層化表示します。
1.CallTree.png

3.3. Page View

 メモリ断片化の内容を表示することができます。
2.PageView.png

3.4. Functions

 メモリの内訳を関数別に表示することができます。
3.Functions.png

3.5. Types

 メモリの内訳をタイプ別に表示することができます。
4.Types.png

その他、ツールの使い方はMemPro Users Guideで説明されています。

4. 使い方

1) 準備

MemPro用のトラッキングを有効にするため [Project].Target.cs に以下のように MEMPRO_ENABLED=1 を追加します。以下はWin64のみトラッキングを適用する例です。

TP_423.Target.cs
public class TP_423Target : TargetRules
{
	public TP_423Target(TargetInfo Target) : base(Target)
	{
		Type = TargetType.Game;
		ExtraModuleNames.AddRange( new string[] { "TP_423" } );

		// Win64でのみMemProトラッキングを有効にする場合以下を追加
		if (Target.Platform == UnrealTargetPlatform.Win64)
		{
			GlobalDefinitions.Add("MEMPRO_ENABLED=1");
		}
	}
}

もしエディタで計測を行いたい場合は、プロジェクトではなくエディタのターゲット [Project]Editor.Target.cs に追記してください。以下はその例です。

TP530Editor.Target.cs
public class TP530EditorTarget : TargetRules
{
	public TP530EditorTarget(TargetInfo Target) : base(Target)
	{
		Type = TargetType.Editor;
		DefaultBuildSettings = BuildSettingsVersion.V4;

// ここから
  		BuildEnvironment = TargetBuildEnvironment.Unique;
  		GlobalDefinitions.Add("MEMPRO_ENABLED=1");
// ここまで
		ExtraModuleNames.AddRange( new string[] { "TP530" } );
	}
}

2) 起動とキャプチャ

 メモリのトラッキングにはLLMを利用するため、起動引数として -llm を指定する必要があります。
それから "MemPro.LLMTag [tag]" で追跡するタグを選択し、"MemPro.Enabled 1" でキャプチャを開始できます。キャプチャを終了する場合はアプリケーションを終了すると自動で停止します。MemProのLaunchから起動引数を定義して起動することも可能です。

起動引数フォーマット
// [LLM_TAG]を好みの設定に併せてください
-llm -nothreadtimeout -execcmds="MemPro.LLMTag [LLM_TAG]" 

以下のケースでは、アプリケーション起動時から全LLMタグのトラッキングを開始します。

例1:全LLMタグでのメモリトラッキングをアプリケーション起動時から開始
-llm -nothreadtimeout -execcmds="MemPro.LLMTag *, MemPro.Enabled 1" 

以下のケースでは、StaticMeshのメモリをトラッキングします。このケースでは起動時に有効にするコマンドを含めていないので、 "MemPro.Enabled 1" を任意のタイミングで実行してキャプチャを開始することができます。

例:StaticMeshタグでのメモリトラッキング準備
-llm -nothreadtimeout -execcmds="MemPro.LLMTag StaticMesh" 

ここで指定することが可能なタグは LLM_ENUM_GENERIC_TAGS のリストを参照。以下の例では "Untagged" に該当します。

	macro(Untagged,	"Untagged",	NAME_None,	NAME_None,	-1)\

キャプチャしたプロファイルは [Project]/Saved/Profiling/MemPro/.mempro_dump 形式で保存されます。
capture.png

5. プロファイルの解析

 MemProでキャプチャした結果をMemProで解析する基本的な方法について記載します。

5.1. MemProでのロードと解析

 MemProでキャプチャを解析する際にシンボル情報を指定することで関数レベルでの情報を確認することができます。以下にMemProでシンボルファイルのパスを指定する方法を記載していますが、予めパッケージにシンボルファイルを含めておくことでキャプチャにシンボル情報を含めることもできます。

・シンボルファイルのパス指定
7.Symbol.png
・デバッグファイルをパッケージに含める
予めProject SettingsでInclude Debug Filesを有効に設定しておく必要があります。
2019-09-14_01h26_31.png

5.2. リークの解析

1) DiffSnapshotの取得

メモリの増減が発生している箇所の差分情報を取得するため、Memory Graphから差分の範囲を Shift+マウス右クリック(ドラッグ) で選択します。選択後に Show Difference を選択すると差分情報が 「Snapshots」 に保存されます。

2023/10/27時点では、左ドラック選択でも行けるようです。

2019-11-26_12h30_35.png

2) CallGraphから差分のチェック

上記で保存された差分スナップショットを右クリックで選択して 「Call Tree」 を選択します。ロードが完了したら差分に関するCall Treeが表示されるため、どの経路で確保されたメモリが残存しているかを確認してリーク箇所を特定します。下の図は「キーを入力した時にCharacterをSpawnした際のメモリ増加箇所」をキャプチャしたものです。APlayerController::ProcessPlayerInputでの入力をトリガに、UWorld::SpawnActorが実行されて、最終的にSkeletalMeshComponentのPhysicsからメモリが確保されていることが分かります。
2019-11-20_15h05_11.png
(※クリックで拡大)

5.3. プロファイル時の注意点

・全LLMタグを指定することで全てのメモリをトラッキングできますがトラッキング量も多くなります
・モバイルなどでキャプチャする場合はLLMタグを指定することをお勧めします
 (予めどのLLMタグでリークが発生しているかを特定しておく必要があります)

6. まとめ

 UE4アプリケーションに関するメモリトラッキングの手段は他にも様々な方法(stat memoryコマンド、Memreportコマンド, Malloc Profiler, LLM, 専用のトラッキングツール等)がありますが、MemProは他のツールとしても非常に使いやすいので5是非お試しください。

[関連記事]
公式ブログ:デバッグとメモリーの最適化
公式ブログ:アンリアル エンジン 4 のメモリリーク対策
Qiita:[UE4] LLM (Low Level Memory Tracker)を使用したメモリトラッキング
Qiita:[UE4] Malloc Profiler/Memory Profiler2を使用したメモリトラッキング

  1. Malloc Profilerは「フルビルドが必要、かつEditor起動時もトラッキングが走る点」が少しやっかい

  2. LLMは「どの経路で確保されたメモリであるかが分からない点」が少し難点

  3. ツールによるメモリトラッキングは「トラッキングコスト、キャプチャに必要なメモリ」などの観点から悩ましい点

  4. 2019/12/18 時点

  5. ※個人の感想です

12
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?