引擎自身中存在記憶體開銷的部分紛繁複雜,可以說是由巨量的“微小”記憶體所累積起來的,比如GameObject及其各種Component(最大量的Component應該算是Transform了)、ParticleSystem、MonoScript以及各種各樣的模組Manager(SceneManager、CanvasManager、PersistentManager等)…
一般情況下,上面所指出的引擎各組成部分的記憶體開銷均比較小,真正佔據較大記憶體開銷的是這兩處:WebStream 和 SerializedFile。其絕大部分的記憶體分配則是由AssetBundle載入資源所致。簡單言之,當您使用new WWW或CreateFromMemory來載入AssetBundle時,Unity引擎會載入原始資料到記憶體中並對其進行解壓,而WebStream的大小則是AssetBundle原始檔案大小 + 解壓後的資料大小 + DecompressionBuffer(0.5MB)。同時,由於Unity 5.3版本之前的AssetBundle檔案為LZMA壓縮,其壓縮比類似於Zip(20%-25%),所以對於一個1MB的原始AssetBundle檔案,其載入後WebStream的大小則可能是5~6MB,因此,當專案中存在透過new WWW載入多個AssetBundle檔案,且AssetBundle又無法及時釋放時,WebStream的記憶體可能會很大,這是研發團隊需要時刻關注的。
對於SerializedFile,則是當你使用LoadFromCacheOrDownload、CreateFromFile或new WWW本地AssetBundle檔案時產生的序列化檔案。
對於WebStream和SerializedFile,你需要關注以下兩點:
- 是否存在AssetBundle沒有被清理乾淨的情況。開發團隊可以透過Unity Profiler直接檢視其使用具體的使用情況,並確定Take Sample時AssetBundle的存在是否合理;
- 對於佔用WebStream較大的AssetBundle檔案(如UI Atlas相關的AssetBundle檔案等),建議使用LoadFromCacheOrDownLoad或CreateFromFile來進行替換,即將解壓後的AssetBundle資料儲存於本地Cache中進行使用。這種做法非常適合於記憶體特別吃緊的專案,即透過本地的磁碟空間來換取記憶體空間。
注意:關於AssetBundle的詳細管理機制,建議檢視AssetBundle技術文章