used_memory_peak_perc太高 memory use report_内存分析


方式1 使用Memreport

Memreport比较快捷

在游戏控制台中输入memreport可得到一份简略的内存分析,输入memreport -full可以得到详细的内存分析。内存报告会保存于Game/Saved/Profiling/MemReports目录下,目录下文件夹名称会包含对应的日期,文件格式为.memreport,可用文本编辑器打开。

这个指令其实是一些指令的组合,可以在BaseEngine.ini中查看并根据需要修改。

memreport的内存分析中包含了内存使用总量、asset的内存使用量、每个类的对象数与内存使用量等。我们可以隔一段时间使用memreport统计一下内存,对比一下二者差异,查看有没有明显的异常。


used_memory_peak_perc太高 memory use report_内存分析_02


方式2和方式3只能同时用一个,两个都开启可能引发死锁,UE目前还在解决这个问题

方式2 使用MallocProfiler

MallocProfiler最详细

  1. 编译MemoryProfiler工具

打开EngineSourceProgramsMemoryProfiler2MemoryProfiler2.sln 工程文件,编译,编译完成后的可执行文件位于EngineProgramsMemoryProfiler2Binaries目录

2. 打开Malloc Profiler的几种方式

.Target.cs中已经提供了开关,根据要编译的类型修改引擎和项目的对应的Target.cs即可,当然也可以修改UE的BuildConfiguration.xml,全局生效

  • 在引擎和项目的.Target.cs构造函数中修改bUseMallocProfiler = true,bOmitFramePointers = false,修改后编译引擎和工程
  • 打开EngineSavedUnrealBuildToolBuildConfiguration.xml,修改bUseMallocProfilerbOmitFramePointers,这种方式是全局性的,包括editor都会打开Malloc Profiler。修改后编译引擎和工程


used_memory_peak_perc太高 memory use report_open cv 打开内存中的位图_03


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按钮即可分析内存


used_memory_peak_perc太高 memory use report_内存分析_04


方式3 使用MallocLeakDetection

MallocLeakDetection可以监视任何尚未得到释放的开发内存分配。这个工具是实验性的,默认情况下会被禁用,实际测试发现不是很稳定,可能会使程序崩溃。也没有提供接口给BuildConfiguration.xml和.Target.cs进行配置,需要手动修改MallocLeakDetection.h:


#define MALLOC_LEAKDETECTION 1


然后重新编译引擎和工程,运行

可在游戏中打开控制台,依次输入mallocleak.start,mallocleak.stop,mallocleak.report进行统计,统计结果会输出到output log或者vs的log中。以下是一个例子:


used_memory_peak_perc太高 memory use report_open cv 打开内存中的位图_05


参考资料:

https://www.unrealengine.com/en-US/tech-blog/dealing-with-memory-leaks-in-ue4

http://wangjie.rocks/2017/10/10/ue4-memoryprofiler/

https://answers.unrealengine.com/questions/338970/how-do-we-use-the-memory-profiler-to-track-memory.html

https://www.unrealengine.com/zh-CN/blog/debugging-and-optimizing-memory