AssetBundle異步加載資源阻塞主線程的疑問

1)AssetBundle異步加載資源阻塞主線程的疑問
2)Memory Profiler中ShaderLab佔用內存大
3)關於C#垃圾回收的問題
4)RenderTexture佔用內存過高
5)Unity 2018.4.17f1異步加載AssetBundle


這是第197篇UWA技術知識分享的推送。今天我們繼續爲大家精選了若干和開發、優化相關的問題,建議閱讀時間10分鐘,認真讀完必有收穫。

UWA 問答社區:answer.uwa4d.com
UWA QQ羣2:793972859(原羣已滿員)

 

AssetBundle

Q:請問AssetBundle.LoadAssetAsync()這個真的是異步獲取資源嗎?我用的是個人版Unity,這個API會阻塞主線程,是不是需要專業版才行呢?

A:AssetBundle.LoadAssetAsync()在加載資源的時候,比如Prefab,它裏面用到的各種Texture、Mesh以及Shader都會在子線程Worker線程中進行加載。但是加載完成後會有後處理,比如Shader.Parse是一定會在主線程處理的,Texture和Mesh需要上傳到GPU。如果開了多線程渲染並使用AUP功能,非RW的Texture和Mesh的上傳會在渲染線程處理;如果沒開多線程渲染,那麼這一部分還是會由主線程來完成。這些後處理的名字叫XXX.AwakeFromLoad,如Texture.AwakeFromLoad,當主線程觸發這些回調的時候,主線程其它的Update操作就必須等這些後處理完成才能繼續。

還有其它的像Prefab的序列化,各種Component的序列化等也都是在主線程完成的。所以一次AssetBundle.LoadAssetAsync操作,其實並不是完全的異步,主線程中依然是要做不少工作。具體細節可以觀看UWA DAY 2019年的視頻,裏面的講解非常清晰:https://edu.uwa4d.com/course-intro/1/91

感謝Xuan@UWA問答社區提供了回答,歡迎大家轉至社區交流:
https://answer.uwa4d.com/question/5e7d54c386713137aaa097c1


Memory

Q:在真機測試環境下的Profiler裏查看Memory使用情況,發現ShaderLab一項佔用內存很大,裏面主要是什麼?

在減少了Shader的變體後這部分內存有所下降 ,沒有使用Unity內置的Standard Shader。有沒有辦法在不減少變體的情況下減少這一塊佔用的內存?

另外,發現同一項下的Objects也佔用很大。

 

A1:ShaderLab是項目在編譯Shader時產生的解析Buffer,其內存增長的特點就是Key words越多、變體越多,其內存佔用越大。目前,還沒有看到在不減少變體的情況下,可以減少該內存佔用的有效方法。如後續有找到,我們也會來及時更新這塊的內容。

97MB過大了,18.9MB其實也較大,但可以接受。至於Objects,建議搜索題庫,來查找之前相應的回答,比如:
https://answer.uwa4d.com/search/objects
該回答由UWA提供

A2:這個過大是因爲某個Shader的Multiple Compile太多導致的,Multiple Compile不會進行Shader裁剪,例如Unity的一個package,Post Process的Uber Shader就是個典型,我把裏邊的Multiple Compile都換成Shader Feature,然後用Shader Variant Collection只定義需要的分支,一個Uber Shader的內存佔用從 30m直接降到忽略不計。但用Shader Feature一定要注意裁剪引起的問題,做好預處理。

感謝bainan@UWA問答社區提供了回答,歡迎大家轉至社區交流:
https://answer.uwa4d.com/question/5a4d8df42b7c402cc97294a3


Mono

Q:一個開發中遇到的問題,請教一下,我在遊戲一開始有個Zip解壓資源的操作(大概150MB左右的Zip包,另開一個線程,非異步操作),解壓完之後大概產生了200MB左右的GC Alloc,結束後不手動調用GC,遊戲經過更新場景->登錄場景->創角場景->主地圖場景(在創角場景到主地圖之間有手動調用GC),進入主地圖後PSS內存大概550MB左右,在Profiler裏看Mono內存,之前解壓產生200MB沒有回收,且後續遊戲一直沒有回收(每個地圖之間切換也有手動GC,但也沒有回收)。

如果我在解壓完之後,短時間內手動調用GC是可以回收的,Profiler裏面的Mono內存回落了,這種情況下進入主地圖PSS只有400MB多一點。總的來說,如果我不及時手動調用GC,解壓產生的GC Alloc就會沒辦法回收,從而常駐內存,這是什麼原因呢?

A:Unity用的bdwgc不支持內存移動,猜測是你後續內存分配比較小,填充了之前解壓產生的空隙部分,造成了碎片化,導致這些塊無法歸還操作系統。200MB的GC Alloc過高,建議拿C/C++重寫一下。

感謝littlesome@UWA問答社區提供了回答,歡迎大家轉至社區交流:
https://answer.uwa4d.com/question/5e787da918502d37b0fc2545


RenderTexture

Q:運行後,就會出現紅框裏的一些RenderTexture,但是遊戲代碼裏所有的new RenderTexture都打Log,發現都沒有執行到。請問,這些RenderTexture可能在什麼地方創建呢?該如何優化呢?

 

A:你這是在編輯器裏看到的,真機不會有SceneViewRT這些,_TargetPool這些應該是由於使用了PostProcessing這類後處理組件產生的。

感謝李星@UWA問答社區提供了回答,歡迎大家轉至社區交流:
https://answer.uwa4d.com/question/5dafd068efeb9d3d55d15b2d


Editor

Q:爲了試試嵌套Prefab,把工程從2017升到2018,然後Windows Editor下就出現奇怪的AssetBundle.LoadAssetAsync載入資源不回調的問題,與此同時,使用LoadAsset同步加載是沒有問題的(真機環境未測試)。

嘗試了調整QualitySettings.asyncUploadTimeSlice增加時間片及QualitySettings.asyncUploadBufferSize增加內存,均不起作用。隨機出現部分資源載不到的問題。但是在PlayMode下,Editor中隨機打開關閉一些界面(非遊戲界面,Editor界面),會觸發異步加載的完成回調,目前暫時找不到規律。

A:在Unity 2018.4.18f1的Release Notes中找到一句話:
Asset Pipeline: Fixed an issue where asset bundles could fail to load when using async loading methods. (1215446)

發現是版本問題,將版本升級到Unity 2018.4.19f1後,此問題不再出現。

感謝題主王嘯予@UWA問答社區提供了回答,歡迎大家轉至社區交流:
https://answer.uwa4d.com/question/5e7c7ba118502d37b0fc2625


今天的分享就到這裏。當然,生有涯而知無涯。在漫漫的開發週期中,您看到的這些問題也許都只是冰山一角,我們早已在UWA問答網站上準備了更多的技術話題等你一起來探索和分享。歡迎熱愛進步的你加入,也許你的方法恰能解別人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官網:www.uwa4d.com
官方技術博客:blog.uwa4d.com
官方問答社區:answer.uwa4d.com
UWA學堂:edu.uwa4d.com
官方技術QQ羣:793972859(原羣已滿員)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章