结论
- Unity 移动端内存主要分三块:资源内存、引擎模块内存、托管堆内存;优化时不要只盯
GC Alloc或 Mono。 - 大多数项目的内存压力来自资源,尤其是 Texture、Mesh、AnimationClip、AudioClip、Material、Shader、Font、Text Asset。
- 判断内存泄漏不能只看“一次进出场景后没有完全回落”,需要做同场景多轮对比、跨场景资源对比和平台内存趋势验证。
- AssetBundle 的问题通常不是“加载失败”,而是 WebStream / SerializedFile / Bundle 对象 / 已加载资源 / 实例化对象的生命周期没有拆清楚。
- 性能优化要形成闭环:确定设备与路径、采集基线、定位类型、修改方案、复测数据、沉淀规则。
资料收敛说明
- 本页已将原先
11条参考链接压缩为2条核心引用,重复导航页、同类 API 细节页和低信噪比补充资料不再逐条公开保留。 - 正文已优先沉淀选型标准、排查流程、风险边界和常用工具定位,后续新增资料应继续转成正文结论,而不是直接堆叠链接。
- 文末只保留官方文档、代表性开源项目和少量仍值得回看的补充阅读。
适用场景
- Android / iOS 包体或运行时内存过高。
- 场景切换后内存没有下降,或者多次切换后持续增长。
- 游戏长时间运行后出现卡顿、闪退、OOM 或系统杀进程。
- Profiler 中出现频繁 GC、加载尖峰、UI 重建或渲染压力。
- 需要做版本发布前的性能巡检和资源审计。
指标口径
Reserved Total:Unity 已向系统申请的总内存,通常大于Used Total,不一定会立刻还给系统。Used Total:Unity 当前实际使用的内存,更适合判断引擎内存和资源内存是否持续增长。Reserved GFX:重点关注纹理和网格资源,通常要从压缩格式、顶点数据、资源冗余和资源泄漏排查。ManagedHeap.UsedSize:逻辑代码申请的托管堆内存,过大通常意味着配置表、容器、字符串、临时对象或缓存策略需要优化。PSS / Instruments:平台侧口径包含系统缓存、驱动、第三方库等,不应和 Unity Profiler 做一一对应,只适合看趋势。
排查流程
- 固定测试条件:设备、系统版本、Unity 版本、资源包版本、画质档位、网络状态、操作路径。
- 采集基线:首包启动、主界面、核心战斗、切场景、长时间挂机、反复打开高频 UI。
- 粗分问题类型:先判断是资源、AssetBundle、托管堆、渲染、UI、第三方插件还是平台侧内存。
- 做快照对比:同一场景不同时刻对比,或主城/战斗等不同场景对比,找“不该共同存在”的资源。
- 对 GPU 渲染瓶颈和移动端抓帧问题,可引入
SnapDragonProfilerCLI这类无头工具链,把高通设备帧捕获、离线分析、HTTP 服务和 WebUI 浏览串成可重复流程,避免只靠本地手工点界面抓数据。 - 查生命周期:确认资源是预加载、常驻缓存、对象池保留,还是被静态变量、容器、事件、单例错误持有。
- 修复后复测:必须用同一路径重新采样,比较峰值、回落值、增长趋势、GC 频率和帧耗时。
高频问题
资源内存
- 纹理通常是移动端最大内存来源,一张
2048x2048非压缩纹理可能直接消耗十几 MB。 - 纹理分辨率影响内存和加载时间,
1024x1024相对512x512通常是 4 倍像素量,不能只凭肉眼提升决定尺寸。 - 非压缩格式如
RGBA32、ARGB32、RGB24显示效果好,但内存占用大;应优先用硬件支持的压缩格式。 - Android 低端兼容常见 ETC1,但 ETC1 不支持 Alpha;可以拆 RGB 与 Alpha,或在中高端设备使用 ETC2 / ASTC。
- UI Sprite 一般不需要 Mipmap;开启后内存大约增加 1/3,且对 UI 渲染收益有限。
Read/Write Enabled只在确实需要 CPU 读写纹理时开启,否则可能让纹理内存翻倍。- Mesh 需要检查无用的 Normal、Color、Tangent;这些顶点属性会增加文件体积和内存,并可能在合批时放大影响。
AssetBundle / 资源生命周期
- 通过
new WWW或CreateFromMemory加载 Bundle 时,容易产生较大的WebStream;通过缓存或文件方式加载通常产生较小的SerializedFile。 CreateFromFile/LoadFromCacheOrDownload更省常驻 WebStream,但可能引入磁盘 IO、文件句柄和PersistentManager.Remapper增长问题。AssetBundle.Unload(false)只卸载 Bundle 对象,已加载资源仍留在内存;如果之后重新加载同一资源,可能出现冗余资源。AssetBundle.Unload(true)会连同已加载资源一起卸载,但容易导致仍被场景对象引用的资源丢失,不适合作为常规粗暴清理手段。Resources.UnloadUnusedAssets()可以清理未引用资源,但 CPU 开销大,不建议在战斗或高频交互中直接调用。- 被静态变量、缓存容器、单例、对象池、事件订阅引用的资源,不会因为
UnloadUnusedAssets()自动释放。
泄漏与冗余
- 进出场景后内存没有完全回落不一定是泄漏,可能是资源常驻、Mono 堆只升不降、系统缓存、驱动缓存或平台统计口径差异。
- 更可靠的判断方式是多次在同一场景之间来回切换:如果 Unity 内存或平台 PSS 持续单调增长,才需要重点怀疑泄漏。
- 资源泄漏常见原因是资源被放进容器、缓存、静态字段或对象池,但场景切换时没有
Remove、Clear或释放引用。 - 冗余资源常见于同一资源被打入多个 Bundle,或运行时修改
Renderer.material导致 Material 实例化。 - 对 Material 变体需求固定的情况,优先制作有限数量的 Material 并切换引用,避免运行时批量产生
(Instance)材质。 - 资源冗余可以按“同一资源数量峰值 > 1”“不该跨场景共同出现”“Bundle 依赖重复打包”三个方向排查。
GC 与托管分配
- 不要在
Update、战斗循环、滚动列表刷新、输入处理等高频路径中持续newClass / Container / Array。 - 即使每帧只分配很少对象,长时间运行也会推高 GC 频率和 Mono 堆峰值。
- 大配置表一次性加载会快速推高 Mono 堆;如果首进游戏 Mono 很高,优先检查配置表是否可拆分、压缩或按需加载。
- 日志输出本身可能造成 CPU 和堆内存开销,线上包应严格控制日志级别、拼接字符串和调用路径。
- 字符串拼接、装箱、闭包、LINQ、临时 List/Dictionary、协程对象、频繁委托创建都需要结合 Profiler 调用栈确认。
- 优先用对象池、容器复用、
StringBuilder、预分配容量、减少临时 lambda 和按需加载降低分配。
动画、粒子与材质
- Animator 对骨骼动画应尽量开启
Optimize Game Objects,减少不必要的 Transform 层级更新;UI Animator 不适用该优化项。 - 动画片段中的 Scale 曲线、过高浮点精度会增加内存,若表现无明显收益,应压缩精度或移除无效曲线。
- 材质切换 Shader 后可能残留无用纹理采样,需要清理不再使用的贴图引用,避免被带进包或运行时占用内存。
- 粒子系统要限制粒子数上限和粒子贴图尺寸;多数普通特效不应默认使用大图和过高粒子上限。
- 纯色纹理可以用 Shader 参数替代,不需要专门占用一张纹理资源。
优化决策
- 优先级一:资源审计。先查大图、非压缩图、UI Mipmap、Read/Write、Mesh 冗余属性、重复资源、未引用资源。
- 优先级二:场景回落。反复切主城/战斗/副本,确认资源是否按预期释放,重点看共同资源和生命周期异常资源。
- 优先级三:加载路径。拆清 AssetBundle 加载方式、卸载方式、依赖关系、缓存策略和大资源初始化时机。
- 优先级四:托管分配。重点清理高频函数分配、大配置表、日志、字符串、临时容器和 UI 刷新路径。
- 优先级五:表现权衡。对纹理尺寸、动画精度、粒子数、网格面数做平台分档,而不是全平台使用同一套高规格资源。
发布前检查清单
- 关键场景是否有性能基线数据。
- 同一路径复测是否至少覆盖 3-5 轮场景切换。
- 纹理是否按平台使用合适压缩格式和合理分辨率。
- UI Sprite 是否误开 Mipmap。
Read/Write Enabled是否只在确实需要 CPU 读写时开启。- Mesh 是否存在无用 Normal、Color、Tangent 或过高面片数。
- 大图、重复图、纯色图、无用纹理采样、未引用资源是否已清理。
- Bundle 是否有明确依赖关系、引用计数、卸载策略和缓存策略。
Unload(false)后是否可能重新加载同一资源造成冗余。UnloadUnusedAssets()是否只在可接受卡顿的时机调用。- 战斗和主界面是否存在持续 GC Alloc。
- UI 高频刷新区域是否已拆 Canvas 或做列表复用。
- 线上崩溃、OOM、ANR 是否能关联到具体版本和资源包。
笔记沉淀方式
- 官方文档和课程链接只放在“参考链接”,正文记录自己验证过的规则、流程和项目经验。
- 同一类问题优先合并到本笔记,例如纹理、AssetBundle、GC、移动端内存。
- 如果某个子主题超过一屏,可以拆成独立笔记,例如
Unity 纹理压缩策略、Unity AssetBundle 卸载机制。 - 本笔记已用
scripts/fetch_link_content.py抓取参考链接正文并缓存到private/link_cache/,缓存不会发布到站点。
渲染优化
- Justin-sky/Nice-Lua: 基于xlua的MVVM框架,支持Addressables, 统一渲染管线等Unity新特性
- Unity3d | 关于RenderTexture/Texture/2d/3d的创建、赋值、保存 - 知乎
- 解决Unity3D中RenderTexture转存png文件,颜色变暗的问题_unity3d rendertexture-CSDN博客
- 线渲染器 (Line Renderer) - Unity 手册
- Unity SortingLayer和Layer区别、相机、渲染顺序和射线检测 - 掘金
- Unity3d中渲染到RenderTexture的原理,几种方式以及一些问题_unity 将3d 角色渲染到render texture上-CSDN博客
- UE4 Shader编译以及变种实现 - UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技
Profiler 与性能分析
- 优化性能和质量 | Unity 的性能分析工具
- Memory Breakdowns | Memory Profiler | 0.7.1-preview.1
- Official - Introducing the Editor Iteration Profiler - Unity Forum
- Unity-Technologies/com.unity.editoriterationprofiler: Assists in capturing frames from the Profiler of Domain Reloads…
- Cysharp/MemoryPack: Zero encoding extreme performance binary serializer for C# and Unity.
- 一文读懂Unity性能分析工具:MemoryProfiler,教你轻松分析项目性能瓶颈_unity memory profiler-CSDN博客
GC 与内存管理
- Unity - Scripting API: Scripting.GarbageCollector.GCMode
- Using custom Editor tools - Unity Manual
- 关于Unity内存优化,你可能遇到这些问题 - UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技
- Unity3D研究院编辑器之脚本获取资源内存和硬盘大小(二十五) | 雨松MOMO程序研究院
- (99+ 封私信 / 80 条消息) 【笔记】Unity内存分配和回收的底层原理 - 知乎
- Unity教程|从零开始构建《杀戮尖塔》|系列视频-P1_游戏热门视频
- Cysharp/NativeMemoryArray: Utilized native-memory backed array for .NET and Unity - over the 2GB limitation and suppo…
- focus-creative-games/hybridclr: HybridCLR是一个特性完整、零成本、高性能、低内存的Unity全平台原生c#热更新解决方案。 HybridCLR is a fully featured, zero…
加载与资源优化
其他参考
- Unity手游实战:逻辑与表现分离以及实战ECS架构和优化 - UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技
- Unity ECS 架构与交通模拟的实现 - UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技
- Unity3d中的细节优化 第一篇 - 知乎
- 【Unity】引擎编译时间优化 - 知乎
- 使用静态织入技术(Fody)简化和优化你的Unity代码 - 知乎
- Unity性能优化分析思路 - UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技
- 《Unity性能优化》— 5. 性能优化实战 | 不特别周のBlog
- Unity JSON性能对比(LitJson、NewtonsoftJson、SimpleJSON) - 锤子猫 - 博客园
- c# - Unity JSON性能对比(LitJson、NewtonsoftJson、SimpleJSON) - 冰封百度的学习笔记 - SegmentFault 思否
- UPR - Unity专业性能优化工具
- Unity着色器编译全流程与优化指南_着色器编译技术-CSDN博客
参考链接
以下链接仅保留正文仍需回看的核心资料入口。