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

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


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問答社區提供了回答async


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問答社區提供了回答spa


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問答社區提供了回答

RenderTexture

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

A:你這是在編輯器裏看到的,真機不會有SceneViewRT這些,_TargetPool這些應該是因爲使用了PostProcessing這類後處理組件產生的。
感謝李星@UWA問答社區提供了回答

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問答社區提供了回答


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

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

相關文章
相關標籤/搜索