計:從加載策略到引用計數(shù)全解析)
開場做第一個商業(yè)化項目的時候,資源管理模塊是我踩坑最深的子系統(tǒng)之一。某次大版本更新后,玩家在連續(xù)切換三個場景后游戲直接閃退,Profiler 抓到的內(nèi)存峰值是 1.8GB。根源是某個 UI 彈窗持有了一份共享特效的Material實例沒釋放,導致它所在的 AssetBundle 始終無法卸載,依賴鏈上幾十 MB 的紋理全部駐留內(nèi)存。更早還翻車過一次:異步加載沒做請求合并,同一幀對同一個 AssetBundle 發(fā)起了 4 次加載,重復 IO 白燒了不說,幾處回調(diào)拿到的資源還互不一致。這兩次事故指向同一個結(jié)論:資源管理不是"調(diào)用Load拿資源"這么簡單,它是一套狀態(tài)機——加載、引用、釋放三個階段必須嚴格閉環(huán)。任何一環(huán)漏了,表現(xiàn)就是內(nèi)存只漲不跌,最后在低端機上閃退。本文就從底層機制出發(fā),把這套模塊怎么設(shè)計講透。一、先理解 AssetBundle 到底是什么設(shè)計之前,得先知道你在管理的東西在引擎里長什么樣。一個.ab文件本質(zhì)上是一個SerializedFile:頭部是元數(shù)據(jù)(包含哪些對象、類型信息、依賴了哪些其他 Bundle),后面跟著壓縮過的對象數(shù)據(jù)塊。Unity 支持不壓縮、LZMA(壓縮率高、解壓慢、整體解壓)和 LZ4(壓縮率中等、按塊解壓、可隨機訪問)三種格式——這就是為什么打 Bundle 時推薦 LZ4:運行時只需解壓用到的塊,加載快、內(nèi)存占用低;LZMA 適合下載分發(fā),但一般要進包后重轉(zhuǎn)。加載也分兩步,理解這兩步是理解一切坑的前提: