关于 Unity 的垃圾回收 (GC) 你可能已经看到不少的文章讨论了。下面是一个极简形式的 Cheatsheet,希望能在最小的篇幅内尽可能全面地列出关于 GC 你需要注意的事项。
Unity GC Cheatsheet
- b01. 避免频繁调用分配内存的 accessors (如 .vertices/.normals/.uvs/.bones)
- b02. 避免频繁调用 Int.ToString() 及其它类型的衍生
- b03. 避免在 Update() 内使用 GameObject.Tag 和 GameObject.Name
- b04. 避免在 Update() 内 GetComponent()
- b05. 避免在 Update() 内 GetComponentInChildren(),可自己实现无 GC 版本
- b06. 避免在 Update() 内访问 animation 组件
- b07. 避免在 Update() 内 FindObjectsOfType()
- b08. 避免在 Update() 里赋值给栈上的数组,会触发堆内的反复分配
- b09. 避免频繁使用 Mathf.Max 等函数的数组版(多于两个参数都会调到数组版)
- b10. (b09 推广):所有具有 params 修饰的函数都应避免频繁使用(以避免临时数组的分配)
- c01. 在不需要时避免使用 GUILayout - OnGUI 时把 useGUILayout 关掉
- c02. 避免使用 foreach (除非遍历数组,或直接用 VS 预编译好的 dll)(Unity 5.5 已修复此问题)
- c03. 避免使用枚举或 struct 做 Key 进行字典查找 (除非使用定制的 comparer)
- c04. 避免使用字符串版本的 Invoke 和 StartCoroutine
- c05. 避免在产品中调用 Debug.Log (生成堆栈字符串)
- c06. 避免在产品中使用 Linq
- c07. 在可能的情况下复用成员变量而不是不断分配新对象
- c08. 初始化 List<> 时指定合理的 Capacity
- c09. 使用 StringBuilder 而不是使用 “+” 或 String.Concat() 拼接字符串
- c10. 在使用协程 yield 时尽量复用 WaitXXX 对象 (使用 Yielders.cs) 而不是每次分配
- c11. 确保 struct 实现了 IEquatable
- c12. 确保 struct 实现了 Equals() 和 GetHashCode()
(完)
Gu Lu
[2017-02-18]