8.Unity性能分析工具-Memory
8.1 知识点
Memory是什么
Memory(内存)模块是 Unity 用来监视内存使用情况的关键工具。它能帮助你识别:哪些资源在占用大量内存,是否存在内存泄漏,是否出现垃圾回收频繁等问题。
游戏开发中常见的内存开销来源:
- 纹理贴图
- 网格
- 音频 / 视频
- 动画
- 材质球和 Shader
- C# 托管堆内存
- 场景中的各 GameObject 以及各组件
- ……等等
在游戏中如果出现以下问题时,可以着重观察这里的内容:
- 游戏卡顿、掉帧
- 表现:游戏突然变慢、不定期小卡顿、操作延迟等
- 可能原因:内存不足导致系统频繁进行垃圾回收(GC),降低游戏帧率
- 闪退、崩溃
- 表现:玩着玩着突然黑屏退出、特定场景(如加载大地图)崩溃
- 可能原因:设备分配不出更多内存,系统强制杀掉进程
- 加载时间变长
- 表现:加载界面等待时间变长,场景切换明显卡顿
- 可能原因:加载资源时需要更多内存,系统调度与 GC 频繁运行
- 发热严重、掉电快
- 表现:手机发烫严重、电池消耗快
- 可能原因:设备内存使用达到极限,系统/游戏频繁调度内存资源,CPU、GPU 都高负载运转
- 低端设备无法运行
- 表现:打开即闪退、进主界面就崩溃
- 可能原因:老旧设备的可用内存更少,超出后甚至无法加载首屏
- 等等等等
Memory中各参数功能的含义和作用
Memory(内存)分析窗口
这里显示的是内存相关的统计信息,常用指标可以这样理解:
- Total Used Memory:已使用的内存总量(包括纹理、网格、对象、脚本等所有内存)
- 最直观的内存压力指标
- Texture Memory:贴图纹理使用的内存总量(包括 Mipmap)
- 通常是内存占用的最大部分
- Mesh Memory:网格使用的内存总量(顶点、索引缓冲等)
- 和场景中物体数量/模型复杂度密切相关
- Material Count:材质数量
- 材质越多越难合批、内存占用也高
- Object Count:内存中的
UnityEngine.Object实例总数(贴图、网格、脚本、GameObject 等)- 过高可能意味着资源未卸载干净、临时对象未销毁
- GC Used Memory:GC(托管堆)使用的内存(堆已分配且仍被使用)
- GC Allocated In Frame:该帧分配的托管堆内存
使用建议:
- 排查 GC 问题时,重点观察
GC Allocated In Frame是否频繁跳动 Texture Memory过高时,检查贴图分辨率是否过大、是否未压缩、是否重复加载Mesh Memory可反映模型复杂度,留意是否存在不合理的高面数网格Object Count超高时,注意对象是否正确卸载、是否存在未销毁的临时 GameObject- 等等等等
Simple视图
Simple 视图展示的是 Unity 运行时的内存占用概况,用于快速判断内存使用情况。它可以帮助我们:
- 看懂 Unity 总共用了多少内存
- 哪些资源类型是主要的内存消耗者
- GC 是否活跃(有没有频繁分配)
- 是否存在异常占用(比如 Profiler 本身占用过大)
- 等等等等
下面是 Simple 视图里常见字段的含义:
Normalized(规范化):将所有帧的内存占用按相同最大值统一缩放显示
- 更直观比较多帧之间各类内存(贴图、堆内存、Profiler、Audio 等)的占用比例变化
- 不勾选时,各帧按自己的比例显示,视觉对比不太直观
- 勾选后更容易分析内存是否稳定,从而查找内存激增、泄漏等问题
Total Committed Memory(总提交内存):Unity 总共已分配的内存(虚拟内存),包括系统预留 + 实际使用
- 即 Unity 请求了多少内存资源,无论是否真正用完
Tracked Memory(跟踪的内存):Unity 能追踪的内存(Memory Profiler 能看见的部分)
- 包括托管堆内存、图形资源、音视频等
In use:实际使用量;Reserved:为未来分配预留的空间
Untracked Memory(未跟踪的内存):Unity 已使用但无法追踪的内存(例如本机插件、Mono/IL2CPP 元数据、DLL 等)
- 如果使用 C++ 插件或
NativeArray没正确释放,会在这里体现出问题
- 如果使用 C++ 插件或
Total Memory Breakdown:总内存细分(总量与总提交内存一致)
- 细分显示为 Unity 哪些子系统分配了多少内存
- Managed Heap:托管堆内存(C# 分配对象内存,会被 GC 回收),同样有
In use/Reserved - Graphics & Graphics Driver:图形/驱动分配的内存(纹理、渲染目标、Shader、网格等)
- Audio / Video:音效/视频系统预估内存使用量
- Other:其它未归类但可追踪的内存(例如编辑器缓存结构)
- Profiler:Profiler 本身占用的内存(采样数据、快照等)
- Untracked Memory:Memory Profiler 无法追踪的内存使用量
Object Stats(对象统计信息):资源类对象的数量与内存分布概况
- Textures / Meshes / Materials / Animation Clips:已加载的纹理/网格/材质/动画剪辑数量与内存
- Assets:已加载的资源总数
- Game Objects:场景中的 GameObject 实例总数
- Scene Objects:Scene 中所有对象总数(GameObject、组件以及场景中不属于资源的内容)
- GC allocated in frame:该帧分配的托管堆内存数量和总大小
注意:即使是空场景也会看到 Textures、Meshes 等对象的分配和内存占用,因为 Unity 会默认加载一些内建资源(内置字体、编辑器图标、GUI 样式、Gizmos 相关资源、Profiler 自己的资源等)。这些内容通常不属于你的游戏资源。
Memory对于我们的意义
Memory 可以帮助我们:
- 精准定位内存占用来源
- 查看哪些内容(脚本、贴图、网格、音频等)占用内存多
- 判断哪些部分可以进行优化压缩、重复利用
- 分析是否存在内存泄漏
- 对比不同帧内存使用情况,发现是否存在不使用但未被释放的内存
- 验证资源卸载是否生效
- 对比不同帧内存使用情况,验证是否如预期释放了资源
- 检查 GC 压力来源
- 排查哪些脚本对象存在大量分配
- 决定内存优化策略
- 根据发现的问题制定优化策略
- 等等等等
8.2 知识点代码
Lesson08_Unity性能分析工具_Memory_Profiler的Memory模块.cs
public class Lesson08_Unity性能分析工具_Memory_Profiler的Memory模块
{
#region 知识点一 Memory是什么
/*
* Memory(内存)模块
* - Unity 中用于监视内存使用情况的关键工具
* - 能帮助识别哪些资源占用大量内存,是否存在内存泄漏或垃圾回收频繁等问题
*
* 游戏开发中常见内存开销来源:
* 1. 纹理贴图
* 2. 网格
* 3. 音频/视频
* 4. 动画
* 5. 材质球和 Shader
* 6. C# 托管堆内存
* 7. 场景中的各 GameObject 以及各组件
* ……等等
*
* 在游戏中如果出现以下问题时,可以着重观察这里的内容:
* 1. 游戏卡顿、掉帧
* - 表现:游戏突然变慢、不定期小卡顿、操作延迟等
* - 可能原因:内存不足导致系统频繁进行垃圾回收(GC),降低游戏帧率
*
* 2. 闪退、崩溃
* - 表现:玩着玩着突然黑屏退出、特定场景(如加载大地图)崩溃
* - 可能原因:设备分配不出更多内存,系统强制杀掉进程
*
* 3. 加载时间变长
* - 表现:加载界面等待时间变长,场景切换明显卡顿
* - 可能原因:加载资源时需要更多内存,系统调度与 GC 频繁运行
*
* 4. 发热严重、掉电快
* - 表现:手机发烫严重、电池消耗快
* - 可能原因:设备内存使用达到极限,系统/游戏频繁调度内存资源,CPU、GPU 都高负载运转
*
* 5. 低端设备无法运行
* - 表现:打开即闪退、进主界面就崩溃
* - 可能原因:老旧设备的可用内存更少,超出后甚至无法加载首屏
*
* ……等等
*/
#endregion
#region 知识点二 Memory中各参数功能的含义和作用
/*
* Memory 中各参数功能的含义和作用:
* - 详见笔记正文(Memory 分析窗口、Simple 视图、字段解释与注意事项)
*/
#endregion
#region 知识点三 Memory对于我们的意义
/*
* Memory 可以帮助我们:
* 1. 精准定位内存占用来源
* 2. 分析是否存在内存泄漏
* 3. 验证资源卸载是否生效
* 4. 检查 GC 压力来源
* 5. 决定内存优化策略
* ……等等
*/
#endregion
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com