一方面是避免記憶體洩漏,另一方面是減少記憶體分配。
避免記憶體洩漏,需要細心的去進行黑盒白盒檢查,一般都是設計上的不合理造成的。同時可以善用 Destroy() 方法,強制釋放非託管記憶體。最好弄清楚 Unity 的資源管理機制,這方面網上教程很多,我就不做搬運工了。
減少記憶體分配,並不是說任何時候都不分配。在關卡進行時要將記憶體分配儘量減少,以降低 GC 的頻率。可以用 Profiler 找出是所有分配了記憶體的地方,再根據經驗判斷是否要進行最佳化。我以前粗略的整理過一些會產生 GC 的操作,可供參考:
生成一個新的委託,例如將方法做為引數傳入
對 List 進行 foreach
用列舉做 Key 進行字典查詢(可能是預設比較器 GetHashCode 時裝箱引起的,提供自定義的比較器應該能解決)
訪問 animation 等元件
獲取 SkinedMeshRenderer.bones 或 Mesh.uvs 之類的屬性
yield return 0 (建議全部替換為 yield return null)
呼叫 GetComponentInChildren(建議自己實現一個無GC版本)
一方面是避免記憶體洩漏,另一方面是減少記憶體分配。
避免記憶體洩漏,需要細心的去進行黑盒白盒檢查,一般都是設計上的不合理造成的。同時可以善用 Destroy() 方法,強制釋放非託管記憶體。最好弄清楚 Unity 的資源管理機制,這方面網上教程很多,我就不做搬運工了。
減少記憶體分配,並不是說任何時候都不分配。在關卡進行時要將記憶體分配儘量減少,以降低 GC 的頻率。可以用 Profiler 找出是所有分配了記憶體的地方,再根據經驗判斷是否要進行最佳化。我以前粗略的整理過一些會產生 GC 的操作,可供參考:
生成一個新的委託,例如將方法做為引數傳入
對 List 進行 foreach
用列舉做 Key 進行字典查詢(可能是預設比較器 GetHashCode 時裝箱引起的,提供自定義的比較器應該能解決)
訪問 animation 等元件
獲取 SkinedMeshRenderer.bones 或 Mesh.uvs 之類的屬性
yield return 0 (建議全部替換為 yield return null)
呼叫 GetComponentInChildren(建議自己實現一個無GC版本)