Unity3D 官方移动游戏优化指南3.内存
Posted Kaitiren
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity3D 官方移动游戏优化指南3.内存相关的知识,希望对你有一定的参考价值。
Unity 为用户生成的代码和脚本采用了自动内存管理。小块数据(如值类型的局部变量)分配在栈上。大块数据和长期存储分配在托管堆上。
垃圾收集器 (GC) 会定期识别并释放未使用的堆内存。虽然这是自动运行的,但检查堆中所有对象的过程可能导致游戏卡顿或运行缓慢。
优化内存使用量意味着注意何时分配和解除分配堆内存,并尽可能减小垃圾收集的影响。
有关更多信息,请参阅了解托管堆。
在内存性能分析器中捕获、检查和比较快照。
使用内存性能分析器
这个独立的附加组件(在 Package Manager 中作为实验性包或预览包提供)可以拍摄托管堆内存的快照,帮助发现碎片、内存泄漏等问题。
在 Tree Map 视图中单击,可跟踪持有内存的原生对象的变量。在这里,可以识别常见的内存使用问题,例如纹理过大或资源重复。
观看如何使用 Unity 中的内存性能分析器来改善内存使用量。还可以查看官方的内存性能分析器文档。
减少垃圾收集 (GC) 的影响
Unity 使用 Boehm-Demers-Weiser 垃圾收集器,它会停止运行程序代码,并且仅在其完成所有工作后才恢复正常执行。 要注意某些不必要的堆分配,这可能会导致 GC 尖峰 :
- 字符串 :在 C# 中,字符串是引用类型,而不是值类型。减少不必要的字符串创建或操作。避免解析基于字符串的数据文件,例如 JSON 和 XML ;改用 ScriptableObject 或 MessagePack、Protobuf 等格式存储数据。如果需要在运行时构建字符串,请使用 StringBuilder 类。
- Unity 函数调用 :请注意,某些函数会创建堆分配。缓存数组引用,不要在循环中分配数组。此外,请使用某些避免产生垃圾的函数 ;例如,使用 GameObject.CompareTag 而不是手动将字符串与 GameObject.tag 进行比较 (返回新字符串会产生垃圾)。
- 装箱 :避免传递值类型变量来代替引用类型变量。这会创建临时对象,以及随之而来的潜在垃圾,例如,int i = 123; object o = i 会将值类型隐式转换为类型对象。
- 协程 :虽然 yield 不会产生垃圾,但创建新的 WaitForSeconds 对象会。缓存并重用 WaitForSeconds 对象,而不要在 yield 行中创建它。
- LINQ 和正则表达式 :它们幕后都会进行装箱,从而产生垃圾。如果性能很重要,请避免使用 LINQ 和正则表达式。如有可能,定时收集垃圾 如果确定垃圾收集冻结不会影响游戏中的某个特定点,则可以使用 System.GC.Collect 触发垃圾收集。 有关在哪些地方可以通过这样做而受益的示例,请参阅了解自动内存管理。 使用增量式垃圾收集器拆分GC 工作负载 增量式垃圾收集使用多个短得多的程序执行中断,而不是单次长时间的中断,将工作负载分布到多个帧上。如果垃圾收集影响了性能,可以尝试启用该选项,看看它能否显著减少 GC 尖峰问题。使用 Profile Analyzer 验证对应用程序的改善。
如有可能,定时收集垃圾
如果确定垃圾收集冻结不会影响游戏中的某个特定点,则可以使用 System.GC.Collect 触发垃圾收集。
有关在哪些地方可以通过这样做而受益的示例,请参阅了解自动内存管理。
使用增量式垃圾收集器拆分GC 工作负载
增量式垃圾收集使用多个短得多的程序执行中断,而不是单次长时间的中断,将工作负载分布到多个帧上。如果垃圾收集影响了性能,可以尝试启用该选项,看看它能否显著减少 GC 尖峰问题。使用 Profile Analyzer 验证对应用程序的改善。
使用增量式垃圾收集器减少 GC 尖峰。
以上是关于Unity3D 官方移动游戏优化指南3.内存的主要内容,如果未能解决你的问题,请参考以下文章