這是摘自Unity官方文檔有關優化的部分,原文鏈接:https://docs.unity3d.com/Manual/BestPracticeUnderstandingPerformanceInUnity.html
總共分為如下系列:
- 采樣分析
- 內存部分
- 協程
- Asset審查
- 理解托管堆 【推薦閱讀】
5.1 上篇:原理,臨時分配內存,集合和數組
5.2 下篇:閉包,裝箱,數組 - 字符串和文本
- 資源目錄
- 通用的優化方案
- 一些特殊的優化方案
內存消耗是關鍵的性能指標,尤其對于在內存資源非常有限的設備上,如移動設備。
剖析內存消耗
分析內存問題最好的工具是Unity在Bitbucket上開源的工具:
https://bitbucket.org/Unity-Technologies/memoryprofiler。
只需要下載對應的代碼倉庫將其放到項目中的Editor目錄下即可。
注意,這個工具在Unity5.3之后的版本都可以使用,如果應用是用IL2CPP打包的,它可以提取原生代碼和托管代碼的內存消耗信息。
使用這個工具,需要使用IL2CPP工具進行打包并且發布到合適的設備上,然后連接上編輯器中的CPU剖析工具,打開內存剖析界面(Window > MemoryProfilerWindow)選擇Take Snapshot。
設備上收集數據,并將這些數據發送給Unity編輯器,應用會暫停一段時間。然后Unity編輯器開始分析數據,這也需要比較久的時間。對于內存比較敏感的應用,這個過程可能需要10-30分鐘完成。
在解析數據和加載的過程中,建議各位耐心等待。
上面的截圖來自于iOS設備上運行的標準Asset場景,顯示了四分之三多的內存給了四個非常大的飛行器的機身紋理貼圖。
這個可視化的工具也可以被放大。點擊每個方塊可以獲得更多的相關信息。
定位重復的紋理
最常見的內存問題是在內存中的資源重復。紋理是最占內存開銷的資源類型,紋理重復是Unity項目中最常見的問題。
如果兩個對象是相同大小,相同類型,那么很有可能這兩個對象是從同一個Asset加載進來的。在新的內存剖析器中,可以通過Name和InstanceID觀察查看資源。
Name是加載進來的Asset文件的名稱,通常不帶路徑名和后綴。InstanceID是Unity采用的內部識別編號,在Unity運行的過程中,這個編號是獨一無二的。
這張圖示范了資源重復的一個例子。圖形的左邊和右邊是從Unity5.4的內存剖析器中的某個細節面板。兩張圖的Asset實際上是內存中兩個分開加載的紋理資源,名字和大小相同。可以在Assets目錄下搜索資源名字,確認是否只有一個資源較這個名字,從而確定是不是資源重復加載。
內存中每個獨立的UnityEngine.Object都有獨特的instance ID,當Object被創建的時候指定。這兩個紋理有不同的Instance IDs,所以它們代表了兩份不同的紋理數據。
因為Asset的大小和名稱相同,而InstanceID不同,所以可以確定一個紋理被加載了兩次。雖然有可能會出現兩個同名的資源文件,所以還是按照文件大小來判定。
AssetBundle和Asset重復
紋理資源和Asset重復的最大原因是AssetBundle的不合理使用。可以參見AssetBundle相關的知道。關鍵章節是管理已經加載的Asset。
檢查圖片緩沖區,圖片效果和RenderTexture內存使用
同樣也可以在剖析器中看到為圖片效果和RenderTexture提供渲染緩沖區占用的內存大小。
上面的截圖展示了使用了Unity電影圖片效果的一個場景的內存剖析器的情況。這個圖片效果分配了臨時渲染緩沖區,而且Bloom效果分配了多個緩沖區。因為iOS設備的高分辨率,這些臨時緩沖區占用了非常多的內存,比項目中剩下的占用的總數還多。
考慮到iPad Air2的分辨率是2048x1536,比大部分終端設備和PC的1080p的分辨率高出了很多。全屏的臨時渲染緩沖區差不多消耗24MB~36MB,取決于緩沖區的格式。降低渲染緩沖區的像素大小可以節省75%的內存消耗,同時也不會對最終的效果造成很大的影響。
優化圖片效果,減少臨時緩沖區和其他的GPU資源的消耗另一個優化方法是創建單個“uber”圖像效果一次執行所有不相干的計算。如果使用Unity5.5或者更新的版本,可以使用新的UberFX。
參見資料:https://github.com/Unity-Technologies/PostProcessing
這個例子提供了一個可以配置化的“uber”圖片效果,可以執行Cinematic Image Effect的所有操作,相比普通的獨立Image Effect可以節省不少資源。
如果覺得文章對您有用,請點個贊唄!???