低级内存跟踪器

概述了如何在您的虚幻引擎项目中使用低级内存跟踪器。

Windows
MacOS
Linux

LLM支持PlayStation 4和XboxOne。Windows作为实验性功能受到支持。

低级内存跟踪器(Low-Level Memory Tracker)(简称 LLM)是一种跟踪虚幻引擎项目中内存使用情况的工具。LLM使用范围标记系统来记录虚幻引擎和操作系统分配的所有内存。

LLM跟踪器

LLM目前有两个跟踪器。每个跟踪器都有自己的分配映射和标记堆栈。默认跟踪器适用于引擎的所有分配。在这两个跟踪器中,它的级别较高并记录通过 FMemory 类函数 Malloc 进行的分配。该跟踪器可为 stat LLMstat LLMFULL 控制台命令提供统计信息。平台跟踪器是较低级别的版本,它记录从OS进行的所有分配。例如,它会跟踪 Binned2 等函数进行的内部分配。因此,默认跟踪器统计信息是平台跟踪器统计信息的子集。

LLM设置

要在项目中启用LLM,请使用以下命令行参数和控制台命令。

命令行参数

说明

-LLM

启用LLM

-LLMCSV

连续将所有值写入CSV文件。自动启用-LLM。

-llmtagsets=Assets

实验性功能。显示每个资源分配的内存总计。

-llmtagsets=AssetClasses

实验性功能。显示每个UObject类类型的总计。

控制台命令

说明

stat LLM

显示LLM摘要。所有较低级别的引擎统计信息都归入单个引擎统计信息。

stat LLMFULL

显示所有LLM统计信息。

stat LLMPlatform

显示从OS分配的所有内存的统计信息。

stat LLMOverhead

显示LLM内部使用的内存。

使用 -LLMCSV 命令行参数时,.CSV 文件将写入 saved/profiling/llm/。该文件将包含每个标记的列,以MB为单位显示当前值。每隔5秒写一个新行(默认情况下)。此频率可以使用 LLM.LLMWriteInterval 控制台变量更改。

LLM标记

引擎(包括游戏代码)的每次内存分配都会被指定一个标记值,用于标识其所属的类别。也就是说,所有内存仅被跟踪一次,没有任何内存错过或被计算两次。所有类别的总计会累计到游戏所用的总内存。

这些标记使用标记范围宏进行应用。在该范围内应用的任何分配都会被分配指定标记。LLM维护有一个标记范围堆栈,并将顶部标记应用于分配。LLM统计信息可以在游戏中使用 stat LLMstat LLMFULL 控制台命令进行查看。每个标记的当前总计将以MB为单位显示。LLM还会将统计信息值写入 .CSV 文件,以便分析这些值。引擎中当前存在以下标记类别:

标记名称

说明

UObject

该标记包括从 UObject 继承的任何类以及由该类序列化的任何内容,包括属性。UObject 囊括了所有未在任何其他类别中跟踪的引擎和游戏内存。请注意,此统计信息不包括单独跟踪的网格体或动画数据。它对应于放置在关卡中的对象数。

EngineMisc

任何其他类别中未跟踪的所有低级内存。

TaskGraphTasksMisc

从任务图中启动的任何没有自己类别的任务。该任务通常级别应较低。

StaticMesh

该标记是 UStaticMesh 类和相关属性,并不包括实际的网格体数据。

要添加新的标记,需要执行以下步骤:

  1. 将值添加到 LowLevelMemTracker.h 中的 ELLMTag 列举类型。

  2. 将相应的元素添加到 LowLevelMemTracker.cpp 中的 ELLMTagNames 数组中。

  3. 使用 LLM_SCOPE 宏将标记范围添加到代码中。

如果范围是特定于平台的,则以相同的方式添加到特定于平台的LLM文件中的列举类型,例如,PlayStation 4的 PS4LLM.cppPS4LLM.h

标记集(实验性)

要使用标记集,请在 LowLevelMemory.h 中定义 LLM_ALLOW_ASSETS_TAGS。使用标记集时,每个分配还将存储资源名称或Object类名称。

使用标记集将增加内存占用和运行时性能耗用。

技术实现细节

LLM的作用原理是维护由指针索引的所有分配的映射。该映射当前包含每个分配的大小及其指定的标记。游戏一次可有多达400万个实时分配,因此内存开销必须尽可能少。当前实现中每个分配使用21个字节:

分配

大小

指针

8个字节

指针散列键

4个字节

大小

4个字节

标记

1个字节

散列图索引

4个字节

使用 OnLowLevelAlloc 函数跟踪分配时,标记堆栈顶部的标记将成为当前标记,并存储在分配映射中,以该指针作为其关键帧。为了避免争用,在单独的 FLLMThreadState 类实例中跟踪每个标记的帧增量。在帧结束时,这些增量将相加并发布到统计信息系统和 .CSV 文件。

LLM早已被初始化,也就是说它必须默认启用。如果未在命令行上启用LLM,它将自行关闭并清理所有内存,以确保没有占用内存。LLM完全在“测试”和“发行”构建中编译。

LLM可在没有统计信息系统的情况下运行(例如在“测试”配置中)。如果这样,屏幕上将无法显示统计信息,但统计信息仍将写入 .CSV 文件。LLM将需要通过修改 LowLevelMemTracker.h 中的 ENABLE_LOW_LEVEL_MEM_TRACKER 来启用。

标记使用范围宏进行应用。以下是两个主要的宏:

  • LLM_SCOPE(Tag)

  • LLM_PLATFORM_SCOPE(Tag)

这两个宏分别设置了默认跟踪器和平台跟踪器的当前范围。这些范围有平台相关版本,例如 LLM_SCOPE_PS4(Tag),它使用特定于平台的标记列举类型。使用统计信息的范围宏(例如 LLM_SCOPED_TAG_WITH_STAT)目前被视为已弃用,不应被使用。

LLM内部使用的所有内存均由平台提供的 LLMAllocLLMFree 函数管理。LLM不以任何其他方式进行分配,因此它不会跟踪自己的内存使用情况(并导致无穷递归),这一点非常重要。

其他技术细节

以下部分介绍了使用LLM时应注意的各种注释和其他信息。

  • 因为LLM占用的内存可能高达100MB甚至更多,所以强烈建议在控制台上以大内存模式运行:

    • 如果使用PlayStation 4,请转至控制台的“目标设置(Target Settings)”,然后将“内存预算模式(Memory Budget Mode)”更改为“LARGE”。

    • 如果使用XBox One,请转至XBox One Manager的“设置(Settings)”选项卡,将“调试内存模式(Debug Memory Mode)”设置为“Pix and Title”。

  • 测试配置中的LLM不会显示屏幕统计信息页面,但会写出 .CSV 文件。在发售时LLM完全禁用。

  • 在PlayStation 4上,LLM需要预留供内部使用的内存(目前为600MB)。如果PlayStation 4移动到新的内存系统(PS4Memory2.cpp),将无需再满足这一要求。

  • 资源标记跟踪仍处于早期实验状态。

Select Skin
Light
Dark

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback