方式1 使用Memreport
Memreport比较快捷
在游戏控制台中输入memreport可得到一份简略的内存分析,输入memreport -full可以得到详细的内存分析。内存报告会保存于Game/Saved/Profiling/MemReports目录下,目录下文件夹名称会包含对应的日期,文件格式为.memreport,可用文本编辑器打开。
这个指令其实是一些指令的组合,可以在BaseEngine.ini中查看并根据需要修改。
memreport的内存分析中包含了内存使用总量、asset的内存使用量、每个类的对象数与内存使用量等。我们可以隔一段时间使用memreport统计一下内存,对比一下二者差异,查看有没有明显的异常。
方式2和方式3只能同时用一个,两个都开启可能引发死锁,UE目前还在解决这个问题
方式2 使用MallocProfiler
MallocProfiler最详细
- 编译MemoryProfiler工具
打开EngineSourceProgramsMemoryProfiler2MemoryProfiler2.sln 工程文件,编译,编译完成后的可执行文件位于EngineProgramsMemoryProfiler2Binaries目录
2. 打开Malloc Profiler的几种方式
.Target.cs中已经提供了开关,根据要编译的类型修改引擎和项目的对应的Target.cs即可,当然也可以修改UE的BuildConfiguration.xml,全局生效
- 在引擎和项目的.Target.cs构造函数中修改bUseMallocProfiler = true,bOmitFramePointers = false,修改后编译引擎和工程
- 打开EngineSavedUnrealBuildToolBuildConfiguration.xml,修改bUseMallocProfiler和bOmitFramePointers,这种方式是全局性的,包括editor都会打开Malloc Profiler。修改后编译引擎和工程
3. 内存分析
- 运行分析,先输入MPROF开启分析,再用MPROF MARK来生成内存快照,也可以MPROF MARK SnapshotName来给快照指定名称输入MPROF STOP命令来停止内存监控,然后会在游戏工程目录SavedProfiling目录下生成以日期时间为后缀的目录,目录中包括.mprof内存记录文件。这个指令是必须的,否则.mprof文件不能用
- 也可以在程序中插桩来取代手动输入命令。首先在EProfilingPayloadSubType的SUBTYPE_LicenseeBase中添加一个枚举类型,然后在FmallocProfiler中添加一个函数:
void FMallocProfiler::SnapshotMemoryMyNewEnumeration(const FString& Tag)
{
if (GMallocProfiler && !GMallocProfiler->bEndProfilingHasBeenCalled)
{
GMallocProfiler->SnapshotMemory(SUBTYPE_XCMEMPROFILE, Tag);
}
}
在程序中需要使用的地方插入如下代码:
MALLOC_PROFILER(FMallocProfiler::SnapshotMemoryMyNewEnumeration(MyTag);)
同样的,需要在MemoryProfiler2的EProfilingPayloadSubType中加入对应的枚举类型
- 运行EngineProgramsMemoryProfiler2BinariesMemoryProfiler2.exe,File->Open打开.mprof文件,然后点击工具栏最后的Go按钮即可分析内存
方式3 使用MallocLeakDetection
MallocLeakDetection可以监视任何尚未得到释放的开发内存分配。这个工具是实验性的,默认情况下会被禁用,实际测试发现不是很稳定,可能会使程序崩溃。也没有提供接口给BuildConfiguration.xml和.Target.cs进行配置,需要手动修改MallocLeakDetection.h:
#define MALLOC_LEAKDETECTION 1
然后重新编译引擎和工程,运行
可在游戏中打开控制台,依次输入mallocleak.start,mallocleak.stop,mallocleak.report进行统计,统计结果会输出到output log或者vs的log中。以下是一个例子:
参考资料:
https://www.unrealengine.com/en-US/tech-blog/dealing-with-memory-leaks-in-ue4
http://wangjie.rocks/2017/10/10/ue4-memoryprofiler/
https://www.unrealengine.com/zh-CN/blog/debugging-and-optimizing-memory