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.内存的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D 官方移动游戏优化指南7.资源

Unity3D 官方移动游戏优化指南7.资源

Unity3D 官方移动游戏优化指南10.音频

Unity3D 官方移动游戏优化指南10.音频

Unity3D 官方移动游戏优化指南10.音频

Unity3D 官方移动游戏优化指南2.性能分析