Unity3D:Memory Profiler 模块

推荐:将NSDT场景编辑器加入你的3D工具链
3D工具集:NSDT简石数字孪生
Memory Profiler 模块
有两种方法可以在 Unity 中分析应用程序的内存使用情况:
- 内存探查器模块:一个内置的探查器模块,可提供有关应用程序使用内存的位置的基本信息。
- 内存性能分析器包:可以添加到项目中的 Unity 包。它会向 Unity 编辑器添加一个额外的内存性能分析器窗口,然后您可以使用该窗口更详细地分析应用程序中的内存使用情况。您可以存储和比较快照以查找内存泄漏,或查看内存布局以查找内存碎片问题。
本页涵盖有关内置 Memory Profiler 模块的信息。 有关 Memory Profiler 包的更多信息,请参阅 Memory Profiler 文档。
内存性能分析器模块可视化表示应用程序中分配的总内存的计数器。您可以使用内存模块查看加载对象的数量以及它们在每个类别中占用的内存总数等信息。您还可以查看每个性能分析器帧的 GC 分配数。
编辑器中的内存分析
在编辑器中分析应用程序时,而不是在目标设备上构建和分析应用程序时,内存性能分析器模块中的性能分析数据大于在其发布平台上运行应用程序时的性能分析数据。这是因为 Unity 编辑器使用占用内存的特定对象,而编辑器窗口本身使用额外的内存。
此外,由于 Unity 无法将性能分析器本身占用的内存与运行模式的内存完全分开,因此性能分析器使用的内存将显示在性能分析器窗口中。为了提醒您这一点,每当将性能分析器目标设置为“播放模式”或“编辑器”时,内存性能分析器模块详细信息窗格的顶部都会显示一条警告。要获得应用程序的更精确数字和内存使用情况,应在要运行应用程序的目标设备和操作系统上分析应用程序。有关详细信息,请参阅有关分析应用程序的文档。
图表类别
内存性能分析器模块分为多个类别,这些类别显示有关应用程序占用内存位置的详细信息。您还可以单击类别的彩色图例以切换其显示。
类别 | 描述 |
---|---|
分配总额 | 应用程序已使用的内存总量。 |
纹理记忆 | 应用程序中的纹理已使用的内存量。 |
网格存储器 | 应用程序中的网格已使用的内存量。 |
材料计数 | 应用程序中的材质实例数量。 |
对象计数 | 应用程序中的原生对象实例数量。 |
GC 已用内存 | GC 堆已使用的内存量。 |
在帧中分配的 GC | GC 堆中每帧分配的内存量。 |
模块详细信息面板
模块详细信息窗格中有两个视图可用,位于 Profiler 窗口的底部:
- 简单:显示每帧内存统计信息的高级概述
- 详细:捕获内存快照,其中包含有关本机对象使用的内存的更多详细信息,包括对它们的本机引用以及 Unity 的不同子系统。
若要更改视图,请从模块详细信息窗格左上角的下拉列表中选择它。
Simple 视图
“简单”视图显示 Unity 如何按帧实时使用内存的概述。它将应用程序使用的总内存分解为几个主要类别。“总计”值基于“系统已用内存探查器”计数器,该计数器指示操作系统 (OS) 报告为应用程序正在使用的内存量。

Unity 为分配留出一些内存池,以避免过于频繁地要求操作系统提供内存。性能分析器模块显示 Unity 保留的内存量,以及性能分析器捕获时 Unity 使用的内存量。
“简单”视图显示在“系统使用的内存性能分析器”计数器中收集的数据。这指示操作系统 (OS) 报告为应用正在使用的内存量,对应于“已提交内存总数”栏和“总内存细分”栏的总值。
在支持从操作系统获取应用程序的总内存大小的平台上,系统内存使用情况超过 0,并且在任务管理器中大小相同。
以下参考表描述了“简单”视图中可用的统计信息,以及其相应的探查器计数器和发布版本中的可用性。此信息也可通过探查器记录器 API 和探查器模块编辑器获得,以便您可以将它们添加到自定义探查器模块中。
属性 | 描述 | 相应的探查器计数器 | 在发布播放器中可用? |
---|---|---|---|
规范化 | 启用此设置可将“已提交内存总数”和“内存总细分”图表缩放到所选帧的内存使用情况。如果禁用此设置,图表将缩放到帧范围内的总已用内存。此设置可帮助您查看内存总量或相对内存量如何随帧变化 | 无 | 无 |
已提交的内存总数 | “已提交内存总数”栏的长度表示 Unity 内存管理器系统跟踪的内存总量、使用的内存量以及未通过此系统跟踪的内存总量。 | 系统使用内存 | 是 |
跟踪内存(使用中/保留) | 指示 Unity 使用和跟踪的内存总量(使用中),以及 Unity 为跟踪目的和池分配而保留的内存量(保留)。 | 已用内存总量 保留内存 总量 | 是 |
未跟踪的内存 | 指示 Unity 已使用但不知道的内存总量。未跟踪内存的一些示例包括: - 通过本机插件或某些驱动程序 分配的内存 - 单声道或 IL2CPP 类型元数据 - 可执行代码和 DLL 使用的 内存 内存探查器包和本机平台提供程序可能具有有关其中一些未跟踪内存量的详细信息。 | 无 | 无 |
总内存细分 | 显示与“已提交内存总数”栏相同的总量,但根据 Unity 为其分配内存的子系统,将其分为一些高级类别。 并非所有内存系统都使用池或区分已用内存和保留内存。那些显示两个数字,已用内存量和保留内存量。如果已用量与保留量不共享相同的单位(B、MB、GB),Unity 将显示该单位,否则将省略该单位。 | 系统使用内存 | 是 |
托管堆(使用中/保留) | 托管代码使用的已用堆大小和总堆大小。此内存被垃圾回收。 | GC 已用内存 GC 保留内存 | 是 |
图形和图形驱动程序 | 驱动程序对纹理、渲染目标、着色器和网格数据使用的估计内存量。 | Gfx 已用内存 Gfx 保留内存 | 否 |
音频 | 音频系统的估计内存使用量。 | 音频已用内存 音频保留内存 | 是 |
视频 | 视频系统的估计内存使用情况。 | 视频已用内存 视频保留内存 | 是 |
其他 | 显示 Unity 跟踪的本机内存,但不在特定计数器下报告。 要获取有关此类别或其他类别构成的详细信息,请在“详细”视图中或使用内存性能分析器包拍摄快照。 重要: “其他”类别不会直接映射到“详细”视图中的“其他”组。在此视图中,“其他”包含未用于图形内存的 GPU 端、性能分析器、音频或视频内存的本机内存的其余部分。 | 无 | 无 |
分析器 | 性能分析器功能使用并从系统中保留的内存。 | 探查器使用的内存探查器保留内存 | 是 |
对象统计信息 | 显示通常占用较高百分比内存的资产类型(纹理、网格、材质、动画剪辑)的对象实例数量,以及它们在内存中的累积大小(资产、游戏对象、场景对象)。 注意:“纹理和网格”内存不会直接映射到“总内存细分”视图中的“图形和图形驱动程序”统计信息。这是因为其中一些内存也可能属于“总内存细分”栏的“其他”类别。 | 对象计数 | 否 |
纹理 | 已加载的纹理总数及其使用的内存。 | 纹理计数 纹理内存 | 否 |
网格 | 已加载的网格总数及其使用的内存。 | 网格计数 网格内存 | 否 |
材质 | 已加载的材质总数及其使用的内存。 | 材料计数材料 记忆 | 否 |
动画剪辑 | 已加载的动画剪辑总数及其使用的内存。 | 动画剪辑计数 动画剪辑内存 | 否 |
资产 | 已加载的资源总数。 | 资产计数 | 否 |
游戏对象 | 场景中游戏对象实例的总数。 | 游戏对象计数 | 否 |
场景对象 | 动态的总数。此数字包括游戏对象计数、组件总数以及场景中不属于资产的所有内容。UnityEngine.Objects | 场景对象计数 | 否 |
在帧中分配的 GC | 显示选定帧中的托管分配量及其总大小(以字节为单位)。 | 帧中的 GC 分配计数 在帧 中分配的 GC | 否 |
播放器中的可用性
您可以使用 ProfilerRecorder API 访问 Player 中内存性能分析器模块的计数器。以下示例包含一个简单的脚本,用于收集总预留内存、GC 预留内存和系统已用内存衡量指标,并将其显示为 GUI。文本区域。内存性能分析器模块信息属于“性能分析器类别”。“内存性能分析器”类别。
using System.Text;
using Unity.Profiling;
using UnityEngine;
public class MemoryStatsScript : MonoBehaviour
{
string statsText;
ProfilerRecorder totalReservedMemoryRecorder;
ProfilerRecorder gcReservedMemoryRecorder;
ProfilerRecorder systemUsedMemoryRecorder;
void OnEnable()
{
totalReservedMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Total Reserved Memory");
gcReservedMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "GC Reserved Memory");
systemUsedMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "System Used Memory");
}
void OnDisable()
{
totalReservedMemoryRecorder.Dispose();
gcReservedMemoryRecorder.Dispose();
systemUsedMemoryRecorder.Dispose();
}
void Update()
{
var sb = new StringBuilder(500);
if (totalReservedMemoryRecorder.Valid)
sb.AppendLine($"Total Reserved Memory: {totalReservedMemoryRecorder.LastValue}");
if (gcReservedMemoryRecorder.Valid)
sb.AppendLine($"GC Reserved Memory: {gcReservedMemoryRecorder.LastValue}");
if (systemUsedMemoryRecorder.Valid)
sb.AppendLine($"System Used Memory: {systemUsedMemoryRecorder.LastValue}");
statsText = sb.ToString();
}
void OnGUI()
{
GUI.TextArea(new Rect(10, 30, 250, 50), statsText);
}
}
以下屏幕截图显示了将脚本添加到 Tanks! 教程项目的结果。

此信息在发布播放器中可用,上表中的其他高级计数器也是如此。如果要在 Profiler 窗口中的自定义模块中查看选定的内存计数器,请使用模块编辑器配置图表。
Detailed 视图
“详细”视图提供应用程序当前状态的快照。选择“取样”按钮以捕获当前目标的详细内存使用情况。探查器需要时间来获取此数据,因此“详细”视图不会提供实时详细信息。探查器取样后,探查器窗口将显示一个列表视图,您可以在其中更详细地浏览应用程序的内存使用情况。

启用模块详细信息窗格顶部的“收集对象引用”设置,以收集有关快照时引用对象的内容的信息。探查器在窗口的右侧窗格中显示此信息。
列表视图将使用内存的对象将分为以下类别:
- Other:资源、游戏对象或组件以外的对象。 其中包括诸如 Unity 用于不同系统的内存之类的信息。
- 未保存:标记为“不保存”的对象
- 内置资源:Unity 编辑器资源或 Unity 默认资源,例如已添加到图形设置的“始终包含着色器”列表中的着色器。
- Assets:从用户或原生代码引用的资源。
- 场景记忆:对象和附加的组件。
单击“资源”或“场景内存”列表中的游戏对象时,Unity 会在“项目”或“场景”视图中突出显示该游戏对象。
注意:在“其他”类别中,“下报告的内存是只读内存”。操作系统可能会根据需要丢弃这些页面,然后从文件系统中重新加载它们。这会产生较低的内存使用量,并且不会直接导致操作系统在使用过多内存时关闭应用程序的决定。其中一些页面也可能与使用相同框架的其他应用程序共享。System.ExecutableAndDlls
此文由3D建模学习工作室整理翻译,转载请注明出处!