12.Unity性能分析工具-MemoryProfiler窗口AllOfMemory
12.1 知识点
All Of Memory(所有内存)的主要作用
All Of Memory 是这个工具中最强大、最底层、最全面的页签。它将内存分配按 内存类别 / 分配方式 进行了分类,适合从全局视角看 Unity 的内存结构与健康状况。
着重要分析的内容:
- 哪些模块分配了最多内存
- 哪些内存是托管的、哪些是原生的、哪些是图形的
- 哪些内存增长但没有释放
- 是否出现了内存碎片、预留过多、未追踪内存暴涨等问题
着重应该关注的内存类别(排查方向):
- 托管内存:排查托管堆占用是否过高,是否有 GC 问题
- 资源所占内存:排查资源对象(纹理、网格、材质球)是否重复加载或未释放
- 图形内存:查看纹理、渲染纹理、网格的显存是否异常,是否因为开启 Read / Write 有双份内存
- 原生分配:排查
NativeArray、UnsafeUtility.Malloc是否有泄漏,特别是使用 DOTS 时 - 未追踪内存:查看是否有无法追踪的大块内存(往往是驱动、平台问题造成的潜在泄漏)
- 预留内存:分析内存碎片或预留过高的区域,确认是否有系统内存无法被释放的情况
All Of Memory(所有内存)界面上的功能参数

这块界面可以按 A / B / C 三部分来理解。
A:Unity 所能识别并追踪到的内存分类

下拉框决定当前表格统计的视角(更偏“占用”还是“是否仍在内存里”):
Allocated Memory(已分配内存)
- 显示 Unity 分配器已分配给对象的内存(可能在虚拟内存或被操作系统回收),一般比驻留内存大一些
- 主要作用:用来分析对象本身理论占用的内存量,可以快速判断大内存对象
Resident Memory on Device(驻留内存)
- 实际驻留在设备物理内存中的部分,表示当前确实占据了内存;排除后台运行或系统清理后的内容,反映对象现在是否还在内存中
- 主要作用:设备内存紧张时判断哪些对象仍常驻,可用于作为优化运行时内存压力的重要依据
Allocated and Resident Memory on Device(分配 + 驻留)
- 综合视图,显示对象分配的总内存以及在设备内存中的驻留情况,通常是最全面的视角;可以直观看出“分类了多少”和“真的在用多少”
- 主要作用:
- 找出大但驻留少的资源(说明更偏临时性:加载后没用 / 被系统回收)
- 找出分配不大但全部常驻的资源(说明常用)
B:所选内容的详细信息(右侧说明面板)
原生内存(Native)

原生内存(Native memory),被以下对象使用:
- 场景对象(如游戏对象和它们的组件)
- 资源(Assets)和管理器(Managers)
- 原生分配(Native Allocations),包括
NativeArray和其他原生容器(Native Containers) - 图形资源在 CPU 端的内存占用
- 以及其他类型的原生对象
补充说明:
- 这个分类不包括 GPU 图形内存,图形内存会在单独的
Graphics类别中显示 - 你可以在
All Of Memory Breakdown(全部内存明细)中进一步查看这些分类的详细信息 - 注意:
Summary(概览)视图和All Of Memory(全部内存)视图中的数值可能不同,因为归类方式不同(分组方式不同)
建议:如果你正在分析某个 Native 内存异常增长,重点查看 All Of Memory 中的 Objects and Allocations 和 Memory Map。
预留内存(Reserved)

“预留内存(Reserved memory)”是指 Unity 向系统(操作系统)申请的内存,但在当前快照捕获时尚未被任何 Unity 对象实际使用。
Unity 有很多原因会为内部分配器提前申请内存,例如:
- 加载资源时预先分配
- 用户在代码中直接进行内存分配
- 内存密集型的计算操作
- GameObject 及其组件的创建与销毁过程
Unity 的大多数内存分配器会按块(chunk)来分配内存。
当某个内存块不再被使用时,它通常会被释放回系统。
但如果你在快照中观察到“预留内存”值很高,大概率是由内存碎片化引起的:当内存碎片化时,某些小对象还残留在一个块中,从而导致整个内存块不能被回收,Unity 仍然保留它。
排查手段:
- 可以在 Memory Profiler 设置中启用
Show reserved memory breakdown(显示预留内存明细),调查哪个分配器占用了最多的预留内存 - 关于 Unity 的各种内存分配器和设置,可以参考官方文档页面:
Memory allocator customization(内存分配器自定义)
如果想减少 Reserved memory,官方建议包括:
- 在加载新场景前先卸载不再使用的资源
- 如果你使用了
UnsafeUtility等底层 API,尽量使用Temp分配器处理生命周期短的分配 - 根据项目需求自定义内存分配器(仅推荐给高级用户),例如 Unity 启动时预分配太多可以调整
建议:这部分数据常用来排查:
- 内存碎片化
- 场景切换后内存未释放问题
- 大块预留内存不回收问题
- 使用了 Unsafe API 但没有释放(
UnsafeUtility.Malloc、NativeArray等)
未标记(追踪)的内存(Untracked)

Untracked Memory(未追踪内存) 是 Memory Profiler 尚无法追踪或归类的内存,原因可能包括:
- 平台特有的内存使用机制
- Memory Profiler 的追踪能力尚未覆盖
- 某些潜在的 bug 或内存记录漏洞
这部分 Untracked 内存的计算方式如下:
- Memory Profiler 会分析整个 Unity 进程中已分配和常驻(resident)的内存区域
- 然后从中减去 Unity 已知的托管内存和原生内存分配器所使用的区域
- 剩下的部分就是无法归类的“未追踪”内存
要进一步分析这些未追踪内存,需要使用平台专用的底层 Profiler(例如 Xcode Instruments、Android Studio Profiler 等)。
补充说明:在计算 Untracked 内存的 Allocated Size(已分配大小) 时,还会从中减去 Graphics(Estimated) 图形内存的大小,因为:
- 我们知道图形设备会申请某些类型的内存区域
- 但无法精确追踪每个图形资源具体映射到哪个内存块
- 所以直接从图形设备相关区域中减去
Graphics(Estimated)的总值 - 若找不到图形区域,则从最大的几个内存区域中扣减这部分图形估算值
建议:
- 想分析图形内存的详细情况 → 用
Allocated Memory视图 - 想准确查看 Untracked 占用了多少内存、是否常驻 → 用
Resident Memory(常驻内存)或Allocated and Resident(分配和常驻) - 如果你遇到 Untracked 非常大 → 建议结合平台原生工具(如 Xcode Instruments 的 VM Tracker、Android 的 meminfo)进一步排查
托管内存(Managed)

包含所有虚拟机内存和托管堆内存。
托管堆(Managed Heap)包含与托管对象相关的数据,以及为这些对象预留的空间。它由脚本垃圾回收器(Scripting Garbage Collector)进行管理,因此任何不再与根对象存在引用链的托管对象都会被回收。
托管内存中“已使用”的部分包括:
- 被托管对象实际使用的内存
- 以及一些无法归还给系统的空闲空间
这个分类中的“已预留(reserved)”内存部分:
- 如果需要可以快速重复利用
- 否则它将在每进行 6 次
GC.Collect垃圾回收时被归还给系统一次
注意:托管堆的预留机制会在一定条件下释放,但空洞/碎片也可能会持续存在,需要通过观察 GC 触发频率来判断是否会长期占用:
- 空洞:内存堆中已被回收但暂时无法重新利用的零散空间(对象大小、对齐、生命周期不同步等原因造成)
- 碎片:内存中零散的空闲空间分布不连续(总空闲很多,但无法满足大对象的分配需求)
托管堆的预留内存(Managed Heap - Reserved)

Reserved memory(预留内存)是指 Unity 的托管堆(Managed Heap)从操作系统申请的内存,但在当前快照时刻,这部分内存并未被任何 Unity 对象实际使用。
托管堆是以 blocks 的形式进行分配的,每个 block 用于存储大小相近的托管对象。每个 block 可以容纳若干此类对象;如果一个 block 在连续多次 GC 后一直保持空状态,那么它会被释放回操作系统。
然而,如果某个 block 被碎片化,只剩下少数几个对象(而原本可以容纳上千个),该 block 仍然被认为是“正在使用中”的,因此它的内存无法释放回系统,这部分仍会被计入 reserved。
注意:即使大部分对象被 GC 清理了,托管堆内存也不会立刻释放掉的原因,常见就是碎片导致的“残留对象”仍让整个 block 被判定为活跃状态,从而继续占据内存。
估算内存使用量视图(Graphics (Estimated))

这是用于图形驱动程序和 GPU 以可视化你的应用程序的估算内存使用量。
这些信息基于 Unity 对图形资源分配的追踪,包括:
RenderTextureTexture(纹理)Mesh(网格)Animation(动画)- 以及其他通过 Unity 或脚本 API 分配的图形缓冲区(Graphics Buffers)
你可以在 All Of Memory 标签页中进一步查看这些图形资源的详细信息。
但并不是所有图形对象的内存都会体现在这个分类中。例如启用了 Read/Write 的图形资源,需要在 CPU 可访问内存中保留一份副本,这会导致其总内存使用量翻倍。你可以使用 Unity Objects 标签页来查看 Unity 对象的总内存使用情况。
另外,并不是所有这类对象的内存都一定实际驻留在 GPU 中。Memory Profiler 无法准确获取图形资源是否实际驻留在 GPU 内存中的信息,因此这里只能提供估算值。
构建代码占用的内存(Executables & Mapped)

由应用程序构建代码占用的内存,包括所有共享库和程序集(无论是托管的还是原生的)。目前,这个数值在不同平台上的报告还不完全一致。
你可以通过以下方式减少这部分内存的占用:
- 使用更高级别的代码裁剪(Code Stripping)
- 减少对不同模块和库的依赖
注意:构建后的代码本身(包括 IL2CPP 编译结果、DLL 等)也会占内存,而且这部分可能随着功能堆积而增长,因此建议裁剪无用代码、精简依赖模块以优化内存占用。
C:内存分配详细情况(表格字段)

- Description:描述;内存分类名或功能模块简要说明
- Allocated Size:已分配内存大小
- % Impact:这项占整个快照内存总量的百分比
All Of Memory(所有内存)与 Unity Objects(Unity对象)页签区别
| 对比点 | Unity Objects(Unity 对象页签) | All Of Memory(所有内存页签) |
|---|---|---|
| 关注角度 | 按 Unity 对象类型分类(如 Texture、RT、Shader 等) | 按内存类别或区域类型分类(如 Native、Managed、Graphics) |
| 分析角度 | 分析指定类型对象占用内存情况 | 分析 Unity 整体内存结构、分配和驻留情况 |
| 排查方向 | 找出哪个资源占用最多 | 分析整体内存健康情况 |
| 定位问题 | 资源暴涨、泄漏的原因等 | 内存碎片、未归类区域、驻留异常等 |
总结:
Unity Objects(Unity对象)页签是面向对象去分析内存使用情况,更适合排查资源、对象等内存问题;更像一个资源仓库清单:列出每类物品(资源)有多少,占用了多少内存All Of Memory(所有内存)页签是面向内存类型去分析内存使用情况,更适合排查系统内存问题;更像一个仓库布局图:列出哪个区域占了多少,是否堆积,是否有空间被浪费
12.2 知识点代码
Lesson12_Unity性能分析工具_MemoryProfiler窗口AllOfMemory.cs
public class Lesson12_Unity性能分析工具_MemoryProfiler窗口AllOfMemory
{
#region 知识点一 All Of Memory(所有内存)的主要作用
/*
* All Of Memory(所有内存)
* - 这个工具中最强大、最底层、最全面的页签
* - 将内存分配按内存类别/分配方式进行了分类
*
* 着重要分析的内容:
* 1. 哪些模块分配了最多内存
* 2. 哪些内存是托管的,哪些是原生的,哪些是图形的
* 3. 哪些内存增长但没有释放
* 4. 是否出现了内存碎片、预留过多、未追踪内存暴涨等问题
*
* 着重应该关注的内存类别:
* - 托管内存:排查托管堆占用是否过高,是否有 GC 问题
* - 资源所占内存:排查资源对象(纹理、网格、材质球)是否重复加载或者未释放
* - 图形内存:查看纹理、渲染纹理、网格显存是否异常,是否因为开启 Read / Write 有双份内存
* - 原生分配:排查 NativeArray、UnsafeUtility.Malloc 是否有泄漏,特别是使用 DOTS 时
* - 未追踪内存:查看是否有无法追踪的大块内存,这往往是驱动、平台问题造成的潜在泄漏
* - 预留内存:分析内存碎片或预留过高的区域,确认是否系统内存无法被释放
*/
#endregion
#region 知识点二 界面上的功能参数
/*
* 界面上的功能参数:
* - 在笔记中进行讲解(A:统计视角下拉框;B:所选内容详情;C:表格字段)
*/
#endregion
#region 知识点三 All Of Memory(所有内存)Unity Objects(Unity对象)页签区别
/*
* Unity Objects vs All Of Memory
* 1. 关注角度:
* - Unity Objects:按 Unity 对象类型分类(Texture、RT、Shader 等)
* - All Of Memory:按内存类别或区域类型分类(Native、Managed、Graphics)
*
* 2. 分析角度:
* - Unity Objects:分析指定类型对象占用内存情况
* - All Of Memory:分析 Unity 整体内存结构、分配和驻留情况
*
* 3. 排查方向:
* - Unity Objects:找出哪个资源占用最多
* - All Of Memory:分析整体内存健康情况
*
* 4. 定位问题:
* - Unity Objects:资源暴涨、泄漏原因等
* - All Of Memory:内存碎片、未归类区域、驻留异常等
*
* 总结:
* - Unity Objects 更像资源仓库清单
* - All Of Memory 更像仓库布局图
*/
#endregion
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com