Q A 記憶體管理(一)

2021-07-29 16:44:02 字數 3360 閱讀 1595

q1:如圖,在editor中檢視profiler裡的記憶體詳細資訊,發現used total中有個「unity」,請問是什麼意思?為什麼會特別大?

在editor中執行時,「unity」大是正常的,因為在editor中執行專案時,引擎包含了所有的資源占用的記憶體(除了部分紋理和mesh是在gfx中),同時自身會進行很多的輔助操作來記錄各種遊戲執行資訊。一般來說,在檢視遊戲執行時的真實消耗記憶體,我們均是推薦直接在發布遊戲上通過profiler進行檢視,在editor中執行遊戲所看到的記憶體是要大很多的。

q2: 在進行記憶體優化時,unity profiler給出的資料和android系統(adb dumpsys meminfo,已經考慮memtrack的影響 )的資料差距較大(已經分析了profiler自身的記憶體占用),如何分析這部分差異,比如包括對視訊記憶體消耗進行準確統計,os消耗的統計等等?

記憶體差異較大是正常的,一般來說,profiler統計的記憶體較為一致,而android系統通過adb反饋的pss、private dirty等值則是差別很大。這主要是因為晶元和os的不同而導致。具體的android記憶體,建議直接檢視google android os的相關文件。

unity profiler反饋的則是引擎的真實物理使用記憶體,一般我們都建議通過profiler來檢視記憶體是否存在冗餘、洩露等問題。

q3:system.executableanddlls佔記憶體巨大,且一直在增長,這個屬於正常情況嗎?

system.executableanddlls該項顯示的是執行檔案和所呼叫的庫(物理、渲染、io等系統庫)的總和。開發團隊不用太擔心該選項的數值,因為很多應用均在共用這些庫,並且它對於真實專案的記憶體壓力非常小,幾乎沒有影響,而且os也不會因為該記憶體而殺掉遊戲或應用。

q4:已經預載入怪物,然後顯示怪物 pss上公升,並且在隱藏怪物後並沒有下降,這是什麼原因導致?視訊記憶體上去了嗎?

僅僅隱藏怪物的話,記憶體是不會下降的。因為隱藏只是改變了gameobject的狀態,並沒有對記憶體中的object和資源進行移除。同時,即使是提前載入了怪物,也依然可能存在以上問題,因為某些資源是在顯示的時候,才會傳輸乙份到gpu的,比如mesh。一般情況下,視訊記憶體都不會即刻降低,這個是由graphics driver來管理的。建議可以看profiler是否增長,如果profiler沒有問題而pss持續增長,就有可能發生了記憶體洩露。

對於這個問題,建議檢視效能優化,進無止境---記憶體篇(下)加深理解。

q5:我們在美術製作時做了40根骨骼,但在動作中僅用到了其中的30根。這種做法和30根骨骼用到了30根相比,在蒙皮計算上會明顯增加嗎?(animation經過了壓縮處理)

理論上是有增加的,骨骼運算均是每個骨骼階段的matrix乘起來的,所以理論上會有開銷。建議使用optimize gameobejct選項,可以減少一些不必要的cpu開銷。

q6:不太明白profiler中managedheap.usedsize是什麼,以及這個引數的意義何在?是否重要?

managedheap.usedsize是專案邏輯**在執行時申請的堆記憶體,該選項只能通過優化**來進行降低。 優化方法一般如下:

managedheap.usedsize過大,一方面可能會影響一次gc的耗時;另一方面也可能反映出指令碼中不合理的gc alloc。

q7:在uwa的幫助下,我們追蹤到了乙個reserved gfx的記憶體占用,並且顯示比較高。我們應當如何降低該記憶體占用呢?

一般來說,reserved gfx 中的記憶體,主要是紋理和網格資源,可以嘗試對紋理格式進行檢測,盡可能使用硬體支援的壓縮紋理;而對於網格資源,則可以從減少頂點或者頂點屬性入手。 具體資訊也可以檢視uwa文件。

另外,更重要的是檢測紋理和網格資源是否存在冗餘(多份一樣的資源)或者洩露(比如,主城中的大紋理出現在戰鬥場景中),這是需要極力避免的。關於資源冗餘、記憶體洩露,開發者可以參考我們之前的文章《 效能優化,進無止境---記憶體篇(下)》。

q8:如果乙個模型對應skinned mesh renderer例項,那其所佔的記憶體會隨著角色增加而增長麼 ?

簡單地從乙個角色prefab例項化(instantiate)出多個例項時,mesh並不會出現多份(這個行為與其他資源是一致的,包括texture,animationclip,material等等)。如果在記憶體中發現多份,可以考慮從專案中assetbundle的載入方式入手,因為即使是同乙個assetbundle中的同乙個角色prefab,如果被反覆進行「載入-例項化-解除安裝」操作,依然是會導致mesh出現多份的(當然其他的資源也是一樣)。

q9:我們的遊戲玩了20分鐘後,texture2d的記憶體漲到了60mb多,並且重複的資源很多,是否由於沒有解除安裝完全?還是打包assetbundle依賴性的問題?用的是ugui。

存在如下兩個原因:

1、ab依賴關係打包存在問題,即atlas沒有被依賴打包;

2、載入解除安裝的管理問題,可能是載入了一次後被乙個container索引了,這時又載入了一次同樣的assetbundle又被索引。如果這些一直沒有釋放,也會出現這種情況。

q10:我們在uwa報告中看到有拼合粒子系統和未拼合粒子系統,請問如何拼合粒子系統?有沒有什麼規則呢?

粒子系統的draw call動態拼合與半透明物體的動態拼合機制相當(粒子基本都是半透明材質)。而對半透明物體,由於其渲染順序的限制(必須從後向前渲染,以保證渲染結果的正確性),動態拼合只能對渲染順序相鄰且材質相同的物體有效。而在決定半透明物體的渲染順序時,unity首先會按shader中的renderqueue進行排序;其次(相同renderqueue時),會根據每個半透明物件到螢幕的距離,距離大的優先渲染。

因此,需要盡可能地將相同材質的粒子系統放在比較接近的深度下,才能更多地使動態拼合生效。但通常由於相機的運動、粒子系統的分散分布等原因造成粒子系統之間的穿插,能夠動態拼合的數量往往都是很少的,所以我們在粒子系統模組看到的開銷分布通常類似該圖,主要都是未拼合粒子系統造成。

Q A 執行效能(一)

q1 如下圖,我們發現waitingforjob這個函式消耗過高導致了卡頓,請問該卡頓是否由於渲染壓力過大導致?從圖中看,該執行緒最後是在等待 canvas.sortjob,而這是 ui 排序造成的開銷 自unity5.2版本開始,ugui的部分計算已經移出了主線程 詳情參考 因此理論上,這是 ui...

QA的管理工具

這個文件模板指的是過程性文件的模板,比如說 立項報告 需求規格說明書 一直到 驗收報告 等,這些應該都有乙個統一的文件模板 包括文件的整體框架 文件的格式等等都需要規範起來。因為在專案過程中,這些文件都是需要存底作為一種驗證的,證明我做過這些事,與甲方溝通確定時必不可少 畢竟你不能最後就只拿個系統給...

iOS記憶體管理 一

1.內總管理原則 引用計數 ios的物件都繼承於nsobject,該物件有乙個方法 retaincount 記憶體引用計數。引用計數在很多技術都用到 window下的com元件,多執行緒的訊號量,讀寫鎖,思想都一樣。一般情況下 後面會討論例外情況 alloc 物件分配後引用計數為1 retain 物...