11.Unity性能分析工具-MemoryProfiler窗口UnityObjects
11.1 知识点
Unity Objects(Unity对象页签)主要内容
这个页签的核心能力:快速定位 Unity 对象内存占用的类型与具体实例。常见用途:
- 查找内存占用最大的资源,判断是否可以压缩、降规格、延迟加载等
- 查找重复加载的资源
- 查看运行时创建但没有释放的资源
- 查看脚本对象是否滞留内存
常见的一些问题(排查方向):
- 纹理贴图内存过高:检查是否重复加载、未压缩、是否开启 Read / Write
- 相同资源是否多次加载:
Name相同但InstanceID不同的对象 - 动态资源未释放:脚本中没有及时释放材质、纹理等
- 多个组件持有大资源引用
MonoBehaviour组件长期驻留:是否存在脚本组件内存泄漏(占着引用没使用)- ……等等
Unity Objects(Unity对象分析窗口)界面上的功能参数

A:对所有 Unity 对象所占内存的组成进行详细分类分析
这里的下拉框决定了当前表格统计的视角(更偏“占用”还是“是否仍在内存里”):
Allocated Memory(已分配内存)
- 含义:Unity 已向操作系统申请的内存总量(可能在虚拟内存或被操作系统回收),一般比驻留内存大一些
- 主要作用:分析对象本身“理论占用”的内存量,快速判断大内存对象
Resident Memory on Device(驻留内存)
- 含义:实际驻留在设备物理内存(RAM)中的部分,表示当前确实占据了内存;排除后台运行或系统清理后的内容,反映对象现在是否还在内存中
- 主要作用:设备内存紧张时,判断哪些对象仍常驻;作为优化运行时内存压力的重要依据
Allocated and Resident Memory on Device(分配 + 驻留)
- 含义:综合视图,显示对象分配的总内存以及在设备内存中的驻留情况,通常是最全面的视角;可以直观看出“分类了多少”和“真的在用多少”
- 主要作用:
- 找出“大但驻留少”的资源(说明更偏临时性:加载后没用 / 被系统回收)
- 找出“分配不大但全部常驻”的资源(说明更常用)
B:所选内容的详细信息
- Managed Type:对象的 C# 类型名
- Managed Assembly:该对象所属程序集
- Native Type:Unity 原生对象的类型名称
- Children Count:该对象的子对象数量(它引用了多少其他对象)
- 注意:不是场景层级的子物体,而是内存引用结构中的“下层持有对象”
- 例:一个材质球可能持有一个着色器和多个纹理
C:对象内存占用情况
- Description:对象简要说明,一般是对象名称
- Allocated Size:该对象在 Unity 进程内部分配器中记录的总分配内存大小
- % Impact:该对象占整体内存的百分比
- Native Size:对象在 Unity 原生内存(C++ 层)中分配的大小(纹理、材质、网格这类通常主要在这里)
- Managed Size:对象在托管内存(C#)中占用的大小
- 例如
MonoBehaviour、ScriptableObject、托管数组、类等对象
- 例如
- Graphics Size:对象在 GPU 图形内存(显存)中占用的估算大小
- 例如纹理像素、
RenderTexture的 RT 缓冲区、Mesh 的顶点/索引缓冲
- 例如纹理像素、
驻留内存(Resident Memory)
真正对设备内存造成压力的,其实是驻留内存(Resident Memory)。
- 它是实际驻留在物理内存(RAM)中的部分,也就是说系统此刻必须为它分配真实的内存
- 一旦超过物理内存上限,就容易造成:
- 系统强制垃圾回收,导致卡顿、掉帧
- 内存溢出(Out of Memory,简称 OOM),系统直接强行杀掉进程
总结:驻留内存决定了程序的生死。
已分配内存(Allocated Memory)
已分配内存(Allocated Memory)数值上可以超过物理限制,不会立刻导致问题。
举例说明:
- 比如申请了 6GB 内存,但其中只有 2.5GB 驻留在 RAM 中
- 就算操作系统没有 6GB 可用内存,依然会“允许”你申请成功(登记虚拟地址空间)
- 但如果你真正想要驻留超过上限的内存,系统会毫不留情地干掉你
总结:申请不是问题,真正驻留、访问才决定生死。
既然已分配内存(Allocated Memory)不决定生死,为什么还要统计它?
- 原因:它虽不决定“立刻死亡”,但决定“健康状况和崩溃风险趋势”
统计它的主要目的:
- 提前预警内存溢出风险
- 高已分配内存(Allocated Memory)意味着迟早会驻留,OOM 只是时间问题
- 衡量资源使用的总体趋势
- 有些内存你还没用到或暂时没驻留,但它反映了程序在“计划”使用的资源规模,是设计是否合理的量化依据
- 识别内存泄漏
- 如果已分配内存(Allocated Memory)一直上涨却没有回落,极可能是资源没有释放或发生了内存泄漏(特别是原生资源或 C++ 插件)
- 优化内存分布结构
- 不合理的内存使用分布(如纹理相关占一半、托管堆相关占很少),可以通过观察已分配内存(Allocated Memory)各子类分布发现
- 与平台限制进行对比
- 虽然当前驻留量没爆,但你可能分配了超过平台上限的内存(比如 Android 中 4GB 上限),一旦压力加大就会踩雷
再次总结:
- 驻留内存(Resident Memory):决定生死(是否 OOM)
- 已分配内存(Allocated Memory):决定体质(是否健康)
虽然最终关心的是内存溢出是否发生,但通过监控已分配内存(Allocated Memory)可以提前发现问题、指导设计和优化,从而防患于未然。
11.2 知识点代码
Lesson11_Unity性能分析工具_MemoryProfiler窗口UnityObjects.cs
public class Lesson11_Unity性能分析工具_MemoryProfiler窗口UnityObjects
{
#region 知识点一 Unity Objects(Unity对象页签)主要内容
/*
* 核心能力:
* - 快速定位 Unity 对象内存占用的类型和具体实例
*
* 常见用途:
* 1. 查找内存占用最大的资源,判断是否可以压缩或延迟加载
* 2. 查找重复加载的资源
* 3. 查看运行时创建但没有释放的资源
* 4. 查看脚本对象是否滞留内存
*
* 常见问题(排查方向):
* 1. 纹理贴图内存过高:重复加载 / 未压缩 / Read-Write
* 2. 相同资源是否多次加载:Name 相同但 InstanceID 不同
* 3. 动态资源未释放:材质、纹理等未及时释放
* 4. 多个组件持有大资源引用
* 5. MonoBehaviour 长期驻留:脚本组件内存泄漏(占着引用没使用)
* ……等等
*/
#endregion
#region 知识点二 界面上的功能参数
/*
* 界面功能参数:
* - 在笔记中讲解(A:内存统计视角下拉框;B:右侧详情;C:表格字段)
*/
#endregion
#region 知识点三 驻留内存(Resident Memory)
/*
* 驻留内存(Resident Memory)
* - 真正对设备造成压力的是驻留内存:它驻留在物理内存(RAM)中
* - 超过物理内存上限时,可能导致强制回收、卡顿掉帧,甚至 OOM 被系统杀进程
*
* 总结:驻留内存决定生死
*/
#endregion
#region 知识点四 已分配内存(Allocated Memory)
/*
* 已分配内存(Allocated Memory)
* - 数值上可以超过物理限制,不会立刻导致问题
*
* 例子:
* - 申请 6GB,但只有 2.5GB 驻留在 RAM 中
* - 系统可能允许你申请成功(登记虚拟地址空间),但当你真的想驻留超过上限的内存时,会直接杀进程
*
* 总结:申请不是问题,真正驻留、访问才决定生死
*
* 为什么还要统计 Allocated Memory:
* - 它虽不决定“立刻死亡”,但决定“健康状况和崩溃风险趋势”
*
* 主要目的:
* 1. 预警 OOM 风险(Allocated 长期偏高,驻留只是时间问题)
* 2. 衡量资源使用总体趋势(反映程序“计划”使用的规模)
* 3. 识别内存泄漏(Allocated 一直涨不回落,尤其原生资源/插件)
* 4. 优化内存分布结构(观察各子类分布是否合理)
* 5. 与平台限制对比(比如 Android 上限,一旦压力加大就踩雷)
*
* 再次总结:
* - Resident:决定生死
* - Allocated:决定体质
*/
#endregion
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com