2
3

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 3 years have passed since last update.

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

Last updated at Posted at 2020-06-08

検証Ver:4.24.3

#1. 結論
 この方法ではメモリーリークを必ず特定できるとは限らないため機能の一例としてご参考ください。
ということで、そこまで技術的な深堀はありません。たまには
この機能は「アンリアル エンジン 4 のメモリリーク対策」で紹介されているものですが、この記事が書かれた2016年から4年も経てば変わることもありますね…。

 メモリトラッキングをしたいのであれば以下のツールや方法をご利用頂くことをおすすめします。

[UE4] LLM (Low Level Memory Tracker)を使用したメモリトラッキング
[UE4] Malloc Profiler/Memory Profiler2を使用したメモリトラッキング
[UE4] MemProを使用したメモリトラッキング

#2. 概要
 MallocLeakReporterはmemreportを利用して差分を取ることによるメモリリーク検出のための機能です。

[制約事項]
・MallocBinned2に対応 (MallocBinned3では利用不可)
 → 4.24の現時点ではWindowsでは利用可能です

 デフォルトでMallocBinned3を使用するプラットフォームは以下の定義を追加してBinned2に切り替えることもできはします。

[Project].Target.cs
        GlobalDefinitions.Add("USE_MALLOC_BINNED3=0");	// 追加 

#3. 事前準備
計測前に以下の3つ手順を行います。

MALLOC_LEAKDETECTIONを有効にするためにTarget.csに以下の定義を追加

[Project].Target.cs
        GlobalDefinitions.Add("MALLOC_LEAKDETECTION=1");	// 追加 

② Debug Symbolを含めるためProject Settingsの**bIncludeDebugFile=TRUE**に変更
③ Developmentでパッケージを作成する

#4. キャプチャ方法
 メモリのトラッキングを行ってレポートを出力する方法は2つありますが以下のコンソールコマンドを利用します。

手動出力の場合

mallocleak.start	// トレース開始
mallocleak.report	// リークレポート取得
mallocleak.stop		// トレース終了 

 mallocleak.startでトレースを開始してからmallocleak.stopでトレース終了するまでの間、mallocleak.reportを実行したタイミングでリークのレポートを出力します。レポートを取得したタイミングでmemreportとリークをトレースした.txtを出力します。

2020-06-08_01h02_04.png

自動出力の場合

mallocleak.start report=n size=m	// トレース開始
mallocleak.stop						// トレース終了 

こちらは上記と殆ど同じですが、memreportの取得周期(s)とフィルタサイズ(KB)を指定します。自動出力にすると以下のように定期的にmemreportの結果を出力します。

2020-06-08_00h21_19.png

#5. リークの解析
 もしリークが見つからない場合は、コンソールのログに以下のような出力を行います。その時にmemreportも出力されます。

リークなし
LogLeakDetector: No leaks found
LogUObjectHash: Compacting FUObjectHashTables data took   X.XXms
LogEngine: MemReportDeferred: saving to ../../../MyProject/Saved/Profiling/MemReports/NewMap-WindowsNoEditor-XX.XX-XX.XX.XX/XXX_NewMap.memreport

 もしリークが見つかった場合は、以下のようにメモリが確保された経路を出力します。デバッグシンボルを含めていない場合はコールスタックも表示されないので、利用の際には含めておく必要があります。

リークあり
AllocSize: 1776 KB, Num: 37, FirstFrame 1572, LastFrame 1890, KnownDeleter: 1, KnownTrimmer: 0, Alloc Rate 0.00B/frame
0x00007ff6546ae3db MyProject.exe!FWindowsPlatformStackWalk::CaptureStackBackTrace() [g:\github\unrealengine-4.24\engine\source\runtime\core\private\windows\windowsplatformstackwalk.cpp:363]
0x00007ff654316380 MyProject.exe!FMallocLeakDetection::Malloc() [g:\github\unrealengine-4.24\engine\source\runtime\core\private\hal\mallocleakdetection.cpp:451]
0x00007ff6543209da MyProject.exe!FMallocLeakDetection::Realloc() [g:\github\unrealengine-4.24\engine\source\runtime\core\private\hal\mallocleakdetection.cpp:519]
0x00007ff654320f14 MyProject.exe!FMallocLeakDetectionProxy::Realloc() [g:\github\unrealengine-4.24\engine\source\runtime\core\private\hal\mallocleakdetectionproxy.h:55]
0x00007ff654386e50 MyProject.exe!FMallocPoisonProxy::Realloc() [g:\github\unrealengine-4.24\engine\source\runtime\core\public\hal\mallocpoisonproxy.h:64]
0x00007ff654386fdd MyProject.exe!FMemory::Realloc() [g:\github\unrealengine-4.24\engine\source\runtime\core\public\hal\fmemory.inl:56]
0x00007ff6569a2fb1 MyProject.exe!TInlineAllocator<4,TSizedDefaultAllocator<32> >::ForElementType<FSimpleElementVertex>::ResizeAllocation() [g:\github\unrealengine-4.24\engine\source\runtime\core\public\containers\containerallocationpolicies.h:553]
0x00007ff656982633 MyProject.exe!FBatchedElements::AddVertex() [g:\github\unrealengine-4.24\engine\source\runtime\engine\private\batchedelements.cpp:113]
0x00007ff65757bbd0 MyProject.exe!FCanvasTextItem::DrawStringInternal_RuntimeCache() [g:\github\unrealengine-4.24\engine\source\runtime\engine\private\userinterface\canvasitem.cpp:1276]
0x00007ff6575774bc MyProject.exe!FCanvasTextItemBase::Draw() [g:\github\unrealengine-4.24\engine\source\runtime\engine\private\userinterface\canvasitem.cpp:903]
0x00007ff65755e685 MyProject.exe!<lambda_196d723fa86b1308605a351ef8f3c4cb>::operator()() [g:\github\unrealengine-4.24\engine\source\runtime\engine\private\userinterface\console.cpp:1551]
0x00007ff6575ab519 MyProject.exe!UConsole::PostRender_InputLine() [g:\github\unrealengine-4.24\engine\source\runtime\engine\private\userinterface\console.cpp:1566]
0x00007ff6575a9e81 MyProject.exe!UConsole::PostRender_Console() [g:\github\unrealengine-4.24\engine\source\runtime\engine\private\userinterface\console.cpp:1350]
0x00007ff656cbb14b MyProject.exe!UGameViewportClient::Draw() [g:\github\unrealengine-4.24\engine\source\runtime\engine\private\gameviewportclient.cpp:1696]
0x00007ff65749ca69 MyProject.exe!FViewport::Draw() [g:\github\unrealengine-4.24\engine\source\runtime\engine\private\unrealclient.cpp:1575]
0x00007ff656c8be12 MyProject.exe!UGameEngine::RedrawViewports() [g:\github\unrealengine-4.24\engine\source\runtime\engine\private\gameengine.cpp:661]
0x00007ff656c9bee8 MyProject.exe!UGameEngine::Tick() [g:\github\unrealengine-4.24\engine\source\runtime\engine\private\gameengine.cpp:1789]
0x00007ff653c9f59b MyProject.exe!FEngineLoop::Tick() [g:\github\unrealengine-4.24\engine\source\runtime\launch\private\launchengineloop.cpp:4485]
0x00007ff653cb1cac MyProject.exe!GuardedMain() [g:\github\unrealengine-4.24\engine\source\runtime\launch\private\launch.cpp:173]
0x00007ff653cb1d6a MyProject.exe!GuardedMainWrapper() [g:\github\unrealengine-4.24\engine\source\runtime\launch\private\windows\launchwindows.cpp:134]
0x00007ff653cc21bf MyProject.exe!WinMain() [g:\github\unrealengine-4.24\engine\source\runtime\launch\private\windows\launchwindows.cpp:263]
0x00007ff6584f8f42 MyProject.exe!__scrt_common_main_seh() 
0x00007ffc9d2ace51 ntdll.dll!UnknownFunction []
2
3
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
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?