Unity Profiler 效能分析
1. CPU
A. WaitForTargetFPS:
Vsync(垂直同步)功能所,即顯示當前幀的CPU等待時間
B. Overhead:
Profiler總體時間-所有單項的記錄時間總和。用於記錄尚不明確的時間消耗,以幫助進一步完善Profiler的統計。
C. Physics.Simulate:
當前幀物理模擬的CPU佔用時間。
D. Camera.Render:
相機渲染準備工作的CPU佔用量
E. RenderTexture.SetActive:
設定RenderTexture操作.
底層實現:1.比對當前幀與前一幀的ColorSurface和DepthSurface.
2.如果這兩個Buffer一致則不生成新的RT,否則則生成新的RT,並設定與之相對應的Viewport和空間轉換矩陣.
F. Monobehaviour.OnMouse_ :
用於檢測滑鼠的輸入訊息接收和反饋,主要包括:SendMouseEvents和DoSendMouseEvents。(只要Edtor開起來,這個就會存在)
G. HandleUtility.SetViewInfo:
僅用於Editor中,作用是將GUI和Editor中的顯示看起來與釋出版本的顯示一致。
H. GUI.Repaint:
GUI的重繪(說明在有使用原生的OnGUI)
I. Event.Internal_MakeMasterEventCurrent:
負責GUI的訊息傳送
J. Cleanup Unused Cached Data:
清空無用的快取資料,主要包括RenderBuffer的垃圾回收和TextRendering的垃圾回收。
1.RenderTexture.GarbageCollectTemporary:存在於RenderBuffer的垃圾回收中,清除臨時的FreeTexture.
2.TextRendering.Cleanup:TextMesh的垃圾回收操作
K. Application.Integrate Assets in Background:
遍歷預載入的執行緒佇列並完成載入,同時,完成紋理的載入、Substance的Update等.
L. Application.LoadLevelAsync Integrate:
載入場景的CPU佔用,通常如果此項時間長的話70%的可能是Texture過長導致.
M. UnloadScene:
解除安裝場景中的GameObjects、Component和GameManager,一般用在切換場景時.
N. CollectGameObjectObjects:
執行上面M項的同時,會將場景中的GameObject和Component聚集到一個Array中.然後執行下面的Destroy.
O. Destroy:
刪除GameObject和Component的CPU佔用.
P. AssetBundle.LoadAsync Integrate:
多執行緒載入AwakeQueue中的內容,即多執行緒執行資源的AwakeFromLoad函式.
Q. Loading.AwakeFromLoad:
在資源被載入後呼叫,對每種資源進行與其對應用處理.
2.GPU Usage
A. Device.Present:
device.PresentFrame的耗時顯示,該選項出現在釋出版本中.
B. Graphics.PresentAndSync:
GPU上的顯示和垂直同步耗時.該選項出現在釋出版本中.
C. Mesh.DrawVBO:
GPU中關於Mesh的Vertex Buffer Object的渲染耗時.
D. Shader.Parse:
資源加入後引擎對Shader的解析過程.
E. Shader.CreateGPUProgram:
根據當前裝置支援的圖形庫來建立GPU工程.
3. Memory Profiler
A. Used Total:
當前幀的Unity記憶體、Mono記憶體、GfxDriver記憶體、Profiler記憶體的總和.
B. Reserved Total:
系統在當前幀的申請記憶體.
C. Total System Memory Usage:
當前幀的虛擬記憶體使用量.(通常是我們當前使用記憶體的1.5~3倍)
D. GameObjects in Scene:
當前幀場景中的GameObject數量.
E. Total Objects in Scene:
當前幀場景中的Object數量(除GameObject外,還有Component等).
F. Total Object Count:
Object資料 + Asset數量.
4. Detail Memory Profiler
A. Assets:
Texture2d:記錄當前幀記憶體中所使用的紋理資源情況,包括各種GameObject的紋理、天空盒紋理以及場景中所用的Lightmap資源.
B. Scene Memory:
記錄當前場景中各個方面的記憶體佔用情況,包括GameObject、所用資源、各種元件以及GameManager等(天般情況通過AssetBundle載入的不會顯示在這裡).
A. Other:
ManagedHeap.UseSize:程式碼在執行時造成的堆記憶體分配,表示上次GC到目前為止所分配的堆記憶體量.
SerializedFile(3):
WebStream:這個是由WWW來進行載入的記憶體佔用.
System.ExecutableAndDlls:不同平臺和不同硬體得到的值會不一樣。
5. 優化重點
A. CPU-GC Allow:
關注原則:1.檢測任何一次性記憶體分配大於2KB的選項 2.檢測每幀都具有20B以上記憶體分配的選項.
B. Time ms:
記錄遊戲執行時每幀CPU佔用(特別注意佔用5ms以上的).
C. Memory Profiler-Other:
1.ManagedHeap.UsedSize: 移動遊戲建議不要超過20MB.
2.SerializedFile: 通過非同步載入(LoadFromCache、WWW等)的時候留下的序列化檔案,可監視是否被解除安裝.
3.WebStream: 通過非同步WWW下載的資原始檔在記憶體中的解壓版本,比SerializedFile大幾倍或幾十倍,重點監視.****
D. Memory Profiler-Assets:
1.Texture2D: 重點檢查是否有重複資源和超大Memory是否需要壓縮等.
2.AnimationClip: 重點檢查是否有重複資源.
3.Mesh: 重點檢查是否有重複資源.
6. 專案中可能遇到的問題
A. Device.Present:
1.GPU的presentdevice確實非常耗時,一般出現在使用了非常複雜的shader.
2.GPU執行的非常快,而由於Vsync的原因,使得它需要等待較長的時間.
3.同樣是Vsync的原因,但其他執行緒非常耗時,所以導致該等待時間很長,比如:過量AssetBundle載入時容易出現該問題.
4.Shader.CreateGPUProgram:Shader在runtime階段(非預載入)會出現卡頓(華為K3V2晶片).
B. StackTraceUtility.PostprocessStacktrace()和StackTraceUtility.ExtractStackTrace():
1.一般是由Debug.Log或類似API造成.
2.遊戲釋出後需將Debug API進行遮蔽.
C. Overhead:
1.一般情況為Vsync所致.
2.通常出現在Android裝置上.
D. GC.Collect:
原因: 1.程式碼分配記憶體過量(惡性的) 2.一定時間間隔由系統呼叫(良性的).
佔用時間:1.與現有Garbage size相關 2.與剩餘記憶體使用顆粒相關(比如場景物件過多,利用率低的情況下,GC釋放後需要做記憶體重排)
E. GarbageCollectAssetsProfile:
1.引擎在執行UnloadUnusedAssets操作(該操作是比較耗時的,建議在切場景的時候進行).
2.儘可能地避免使用Unity內建GUI,避免GUI.Repaint過渡GC Allow.
3.if(other.tag == GearParent.MogoPlayerTag)改為other.CompareTag(GearParent.MogoPlayerTag).因為other.tag為產生180B的GC Allow.
F. 少用foreach,因為每次foreach為產生一個enumerator(約16B的記憶體分配),儘量改為for.
G. Lambda表示式,使用不當會產生記憶體洩漏.
H. 儘量少用LINQ:
1.部分功能無法在某些平臺使用.
2.會分配大量GC Allow.
I. 控制StartCoroutine的次數:
1.開啟一個Coroutine(協程),至少分配37B的記憶體.
2.Coroutine類的例項 — 21B.
3.Enumerator — 16B.
J. 使用StringBuilder替代字串直接連線.
K. 快取元件:
1.每次GetComponent均會分配一定的GC Allow.
2.每次Object.name都會分配39B的堆記憶體.