技术分享连载(八十九)
內存
Q1:我寫了一個用例加載AssetBundle,并將多個特效Prefab實例化到場景中。連續運行了多次用例并把添加的特效對象都刪除,而且切換了場景,我看到Profiler中的內存變化如下圖所示:
我想咨詢下:
1. Profiler里的Reserverd Unity內存比Used Unity內存高出很多是正常的嗎?
2. 如果正常的話,有辦法可以回收Reserverd Unity內存嗎?
3. Reserverd Unity內存在運行完多次上述的用例后穩定在400MB,再運行一次用例可以上漲到450MB,雖然后面會回落到400MB。這樣的表現也是正常的嗎?
題主這個數據是在Editor中做測試的結果嗎?Reserverd比Used高出這么多確實不太合理;但如果是Editor中,那么Unity其實會做很多輔助操作,這些也確實是會占用內存的。所以,建議在真機中測試看看,看看這個差距是否會下來。但如果是在真機中,那么這個差距確實過高了,不太合理。
Reserverd Unity的內存是引擎自身管理的,一般會在后續不使用時自己降下來。
這種升高和回落是正常的,但至于是否應該這么高,請見1中的回答。
該問題來自UWA問答社區,如您對該問題仍有疑問,可以轉至社區進行進一步交流。
https://answer.uwa4d.com/question/5a1fde25bd7d86f726903207
內存
Q2:我想咨詢下,Resources.UnloadUnusedAssets() 在卸載舊場景后加載新場景前調用好,還是在加載新場景后調用比較好呢?如果考慮內存峰值的話,我覺得是前者好,但是在UWA上看到有些文章說是加載場景后調用,所以想深入學習下。
如果題主是通過LoadLevel(Async)類似的方式來加載場景的話,那么Unity自身會在底層執行一次類似Resources.UnloadUnusedAssets的操作。所以,這時如果手動調用Resources.UnloadUnusedAssets操作,時間間隔很短,其實這個是有些重復的。因此,我們才建議在新場景加載后再調用一次。
但如果題主使用LoadLevelAdditive或其他類似的API來切換場景的話,那么Unity是不會調用Resources.UnloadUnusedAssets的,這時你再舊場景卸載后調用,其實也是很不錯的選擇。
該問題來自UWA問答社區,如您對該問題仍有疑問,可以轉至社區進行進一步交流。
https://answer.uwa4d.com/question/5a1fc7dbbd7d86f726903206
渲染
Q3:是否可以認為Shader里 Blend Off和Blend One Zero是完全等價的?我在Unity的Standard Shader里看到它的混合是使用形如Blend [_SrcBlend] [_DstBlend]來動態控制,并且注意到其在StandardShaderGUI.cs里設置Opaque時就是設置的 Blend One Zero,那么是否可以認為在Shader里寫Blend One Zero的話,和Blend Off是等價的?Unity會自動改變blendstate從而避免從destbuffer讀取數據?
我們在Unity 2017.1上測試了一下,發現實際上在Android平臺的GLES調用中,Unity的Standard Shader的Opaque模式是在disable blend的狀態下渲染的,實驗如下:
設備:紅米2。渲染場景是兩個Standard Shader Opaque模式物體(Sphere和Cube),中間有一個Unlit Transparent的Quad:
通過Android工具查看GLES API調用發現,每一幀渲染Cube和Sphere的時候Blend都是關閉狀態(上一幀結束時關掉),然后在渲染Unlit Transparent的Quad時打開:
其中,36個頂點的DC是渲染Cube,2304個頂點的DC是渲染Sphere,6個頂點的 DC是渲染quad。所以看起來Standard Shader的Opaque模式應該是glDisable(GL_BLEND)的狀態下渲染的。
該問題來自UWA問答社區,如您對該問題仍有疑問,可以轉至社區進行進一步交流。
https://answer.uwa4d.com/question/5a1a8e710aef30913881b489
內存
Q4:在游戲每次打完副本回到主界面后,內存數據總是不太一致,其中通過Unity Profiler我觀察到ManagedHeap.ReservedUnuseSize和ManagedHeap.UseSize的數值一直在變化,請問這個變化是否是合理的?
ReservedUnuseSize和ManagedHeap.UseSize一直在變化是正常的,它們都屬于Mono內存,前者是當前Mono內存中沒有使用的,后者是正在使用的。一般游戲中,Mono堆內存是會經常由代碼來進行分配的,所以這兩個值一直在變化,也是很正常的情況。
這里建議題主密切關注以下兩點:
(1)Mono的總堆內存是否一直在升高
下圖是UWA性能測評報告中的Mono堆內存走勢圖,其中的紫色線條即為項目運行時的ManagedHeap.UseSize,而黃色線條為ReservedUnuseSize,這兩者都是在變化的,但最需要關心的是藍色線條Reserved Mono,這條線條如果持續往上走,那么就說明項目中是很可能出現了內存泄露問題,需要研發團隊徹查,建議通過Mono詳細堆內存分析來進行修復。
(2)具體的堆內存分配是否合理
ManagedHeap.UseSize或者Mono總內存的上升都是由于代碼的堆內存產生的,所以查看代碼堆內存分配是否合理,避免不必要的堆內存分配是非常重要的,類似于下圖。
建議題主參考以下兩篇文章:
- 用正確的方式,三天搞定Mono堆內存泄漏!
- Unity游戲的代碼堆內存優化
原文出處:侑虎科技
本文作者:admin
轉載請與作者聯系,同時請務必標明文章原始出處和原文鏈接及本聲明。
總結
以上是生活随笔為你收集整理的技术分享连载(八十九)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 优化就是在和时间赛跑
- 下一篇: jfinal-swagger让你的应用接