Help us understand the problem. What is going on with this article?

[UE4] Malloc Profiler/Memory Profiler2を使用したメモリトラッキング

1. はじめに

 Malloc ProfilerはEngineに組み込まれているツールでメモリのプロファイルを書き出します。ここで書き出したプロファイルはMemory Profiler2というツールで読み込むことでメモリリークやメモリ関連の問題を発見するために役立ちます。Malloc Profilerは、WindowsでのサポートをメインにLinux/iOS/Macでも機能します(Androidは...)。しかしプロファイルにあたっては膨大な十分なメモリを必要とするため、計測にはパッケージ済のWindowsビルドでプロファイルを実行するのが概して好ましいです。
 検証は4.21.1にて実施しています。
2018-12-16_14h21_38.png

2. 注意点

 事前に認識しておくべきいくつかの注意点があります。
・Profileを有効にする際、プロジェクトをリビルドする必要があるため時間を要します
・Profileを実行すると膨大なプロファイリングのメモリを必要とするためPCで実行するのが安全です
・上記の理由により、メモリが枯渇するため長期間キャプチャしないようにしてください (無操作15分で2GB程度になります)

3. Memory Profilerで出来ること

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

3.1. Callgraph View

 メモリがAllocateされるまで経路の階層化表示します。Topdown式でMemory Allocationの概要が分かります。もしパッケージしたゲームで表示されない場合は、予めProject SettingsでInclude Debug Filesを有効に設定しておく必要があります。
1.CallGgraph.png

3.2. Exclusive View

 メモリリークを発見するには Exclusive view が最も役に立つはずです。デフォルトではプロジェクト起動以降に実行された全てのMemory Allocationが表示されます。サイズの大きいAllocationを見つけるのに有効です。
2.Exclusiveview.png

3.3. Timeline View

 Timeline Viewは時間経過に伴ったMemory Allocationの概要が表示されるので、リークしていることを傾向的に確認することができます。またCustom Mark Points(独自のMarker)も作成することができます。そのためには、タイムライン上の特定のポイントを選択します。再度、プロファイルを開くとこれらのMark PointsがStart/Endのドロップダウンメニューで利用できるようになります。
3.TimelineView.png

3.4. Histgram

棒軸グラフで統計データを表示します。メモリの占有率を視認しやすいため、何にメモリを多く使用しているかを確認することができます。
4.Histgram.png

3.5. Memory Map

Memory Mapを表示します。メモリを効率的に使用できているかを確認することができます。
5.MemoryMap.png

3.6. Details View

Point-To-Pointでメモリの増減を確認することができます。Start/Stopはプロファイルされた2点を上部のDiff Start/Diff Endから調整することができます。Diffはその差分情報を示し、現象した場合はマイナス値で表示します。
6.DetailsView.png

4. 準備

プロファイルを開始するまでに事前に準備が必要です。以下に手順を示しますが、準備を開始する前に全ての手順を確認してから実施することをお勧めします(これは準備に時間がかかることと、Editorでの動作に影響が出るため)。

[準備手順]
① Memory Profiler2の起動確認
② Malloc Profileの有効化
③ パッケージの作成

4.1. Memory Profiler2の起動確認

Memory Profiler2が動作可能なことを先に確認しておきます。もし、Engine/Programs/MemoryProfiler2/Binariesに実行ファイル(.exeファイル)が存在していない場合は、先にMemory Profiler2の実行ファイルを作成するためにコンパイルする必要があります。コンパイルするためには、Engine/Source/Programs/MemoryProfiler2/MemoryProfiler2.slnを起動してプロジェクトをビルドします。ビルドが完了したら、実行ファイルが作成されるためMemory Profiler2が起動できることを確認します。
2018-12-15_23h38_00.png2018-12-15_23h41_52.png

4.2. Memory Profileの有効化

プロファイルを行うためにMalloc Profilerを有効にします。

2020/04/28 追記
「以前のやり方」だとEditorでもProfilerが動作してしまい使い辛いので、こちらがおススメです。

有効化するためには[Project].Target.csに以下のようにbUseMallocProfiler=trueを追加してプロジェクトのビルドを実行します。

public class TP_424Target : TargetRules
{
    public TP_424Target(TargetInfo Target) : base(Target)
    {
        Type = TargetType.Game;
        DefaultBuildSettings = BuildSettingsVersion.V2;
        bUseMallocProfiler = true;                  // ← コレを追加
        ExtraModuleNames.AddRange( new string[] { "TP_424" } );
    }
}

以前のやり方

有効化するためには、BuildConfiguration.xmlに以下のようにbUseMallocProfilerを有効にするための設定を追加してプロジェクトのリビルドを実行します。

\Engine\Saved\UnrealBuildTool\BuildConfiguration.xml
<?xml version="1.0" encoding="utf-8" ?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
  <BuildConfiguration>
      <bUseMallocProfiler>true</bUseMallocProfiler>
  </BuildConfiguration>
</Configuration>

下記は上記の設定と同じであるため、既に上記を実施してビルドを実行している場合は設定する必要はありません。

\Engine\Source\Programs\UnrealBuildTool\Configuration\TargetRules.cs
        /// <summary>
        /// If true, then enable memory profiling in the build (defines USE_MALLOC_PROFILER=1 and forces bOmitFramePointers=false).
        /// </summary>
        [XmlConfigFile(Category = "BuildConfiguration")]
        public bool bUseMallocProfiler = true;

4.3. パッケージの作成

ゲームのフルビルドが完了したら、後はパッケージを作成すればプロファイルの準備が完了です。

※Editorの起動時間がかかるようになっているかもしれません。これはEditorの起動時にもMalloc Profileが動作しているためです。[Game]/Saved/Profilingを見るとプロファイル(.mprofファイル)が作成されていることが確認できます。そして膨大なメモリをプロファイリング実行しています。本来はEditorからではなくInstalledBuildなどで作成して自動化するべきですが、残念ならEditorで実行する場合はEngineをカスタマイズしない限りこのようにプロファイルが作成されてしまいます。

2020/04/28 追記
※4.2.章で追記した内容(BuildConfigurationでの定義ではなくTarget.cs)での定義とすれば、パッケージのみでMallocProfilerを動作させることができます。

5. プロファイル

プロファイルはアプリケーションを起動すると直ぐに開始します。そしてアプリケーションを終了するとプロファイルを終了します。基本的なプロファイルの開始と終了はこの2点です。プロファイルを終了すると[Game]/Saved/Profilingにプロファイル(.mprofファイル)が書き出されます。Memory Profiler中はゲームがプロファイリングの負荷によって低速になります。
2018-12-16_18h21_07.png

「プロファイリングの開始」はMallocProfilerが生成されたタイミングのみしか存在しないため、1度しか開始を実行できません。つまり、1度プロファイルを停止してしまうと再開できないということで。プロファイリングの終了はアプリケーションの終了以外にコンソールコマンドによって特定のタイミングで停止することができます。これ以外にも、レベルの遷移時やコンソールコマンドからプロファイルの中間ポイントをマーキングすることができます。

Command 機能
Mprof Start プロファイル開始用のコマンド (効果はありません)
Mprof Stop プロファイル終了用のコマンド (1度終了すると再開できません)
Mprof Mark [MARK_NAME] プロファイルの中間ポイントを記録します
DumpAllocStoFile Mprof Stopと同じ
SnapshotMemory Mprof Markと同じ

6. プロファイルの解析

 プロファイルを取得したら、後はプロファイラで解析するだけです。以降にMemory Profiler2での解析について説明します。

6.1. Memory Profiler2でのロードと解析

Memory Profiler2から保存された.mprofファイルを開きます。これには時間がかかる(約1分程度)ことがあります。
2018-12-16_16h18_54.png
プロファイルをロードしても直ぐには反映されません。各タブに移動した後、画面右上にある「GO」ボタンを押すことで反映されます。
2018-12-16_16h14_39.png
特定のメモリリークを見つけ出すにはDiff StartとDiff Endを調整してプロファイルされた期間を調整します。ここには実行時に追加した Markerを選択することができます。もしくは特定のイベント時(マップの遷移時、GC時など)に自動的に生成されたMarkerを選択することも可能です。

2018-12-16_15h49_26.png

6.2. リークの解析

例えば以下のようにメモリが増加しているような場合、どこで何が追加されたのかを追跡します。これはアプリケーション起動からThirdPersonTemplateのMapが起動するまでのトラッキングの記録なので、当然レベルが生成された際に追加されたメモリが追加されます。
2018-12-16_20h04_09.png
Details ViewのDiffを見るとどの程度のメモリが増加したかを確認できます。Diffはアプリケーション起動時からの差分なので、当然追加された分がDiffに記録されています。
2018-12-16_20h05_39.png
Execulsive Viewを見ると、どのようなメモリがどこで追加されたかを確認できます。このように、得られた結果が想定されたものか、不用意に増えていないかなどを確認し、リークしている箇所を特定します。
2018-12-16_20h08_52.png

7. まとめ

Memory Profilerは便利なツールですが、使用条件が限られる点や準備に時間がかかる点などがあるツールです。しかしながら、メモリのトラッキングを正確にPickupでき、また専用のツールを持たないWindowsなどでは十分に役に立つツールです。メモリトラッキングが必要なケースは大抵の場合が開発の終盤(エージングテストなど)であるため、予めどのようなツールか触れておくのも有事の際に便利です。

donbutsu17
主にUnreal Engineに関する記事を書きます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした