天天看點

技術分享連載(八十九)

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的,這時你再舊場景解除安裝後調用,其實也是很不錯的選擇。

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)的狀态下渲染的。

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

轉載請與作者聯系,同時請務必标明文章原始出處和原文連結及本聲明。

繼續閱讀