技术分享连载(八十九)
內(nèi)存
Q1:我寫了一個用例加載AssetBundle,并將多個特效Prefab實例化到場景中。連續(xù)運行了多次用例并把添加的特效對象都刪除,而且切換了場景,我看到Profiler中的內(nèi)存變化如下圖所示:
我想咨詢下:
1. Profiler里的Reserverd Unity內(nèi)存比Used Unity內(nèi)存高出很多是正常的嗎?
2. 如果正常的話,有辦法可以回收Reserverd Unity內(nèi)存嗎?
3. Reserverd Unity內(nèi)存在運行完多次上述的用例后穩(wěn)定在400MB,再運行一次用例可以上漲到450MB,雖然后面會回落到400MB。這樣的表現(xiàn)也是正常的嗎?
題主這個數(shù)據(jù)是在Editor中做測試的結(jié)果嗎?Reserverd比Used高出這么多確實不太合理;但如果是Editor中,那么Unity其實會做很多輔助操作,這些也確實是會占用內(nèi)存的。所以,建議在真機(jī)中測試看看,看看這個差距是否會下來。但如果是在真機(jī)中,那么這個差距確實過高了,不太合理。
Reserverd Unity的內(nèi)存是引擎自身管理的,一般會在后續(xù)不使用時自己降下來。
這種升高和回落是正常的,但至于是否應(yīng)該這么高,請見1中的回答。
該問題來自UWA問答社區(qū),如您對該問題仍有疑問,可以轉(zhuǎn)至社區(qū)進(jìn)行進(jìn)一步交流。
https://answer.uwa4d.com/question/5a1fde25bd7d86f726903207
內(nèi)存
Q2:我想咨詢下,Resources.UnloadUnusedAssets() 在卸載舊場景后加載新場景前調(diào)用好,還是在加載新場景后調(diào)用比較好呢?如果考慮內(nèi)存峰值的話,我覺得是前者好,但是在UWA上看到有些文章說是加載場景后調(diào)用,所以想深入學(xué)習(xí)下。
如果題主是通過LoadLevel(Async)類似的方式來加載場景的話,那么Unity自身會在底層執(zhí)行一次類似Resources.UnloadUnusedAssets的操作。所以,這時如果手動調(diào)用Resources.UnloadUnusedAssets操作,時間間隔很短,其實這個是有些重復(fù)的。因此,我們才建議在新場景加載后再調(diào)用一次。
但如果題主使用LoadLevelAdditive或其他類似的API來切換場景的話,那么Unity是不會調(diào)用Resources.UnloadUnusedAssets的,這時你再舊場景卸載后調(diào)用,其實也是很不錯的選擇。
該問題來自UWA問答社區(qū),如您對該問題仍有疑問,可以轉(zhuǎn)至社區(qū)進(jìn)行進(jìn)一步交流。
https://answer.uwa4d.com/question/5a1fc7dbbd7d86f726903206
渲染
Q3:是否可以認(rèn)為Shader里 Blend Off和Blend One Zero是完全等價的?我在Unity的Standard Shader里看到它的混合是使用形如Blend [_SrcBlend] [_DstBlend]來動態(tài)控制,并且注意到其在StandardShaderGUI.cs里設(shè)置Opaque時就是設(shè)置的 Blend One Zero,那么是否可以認(rèn)為在Shader里寫B(tài)lend One Zero的話,和Blend Off是等價的?Unity會自動改變blendstate從而避免從destbuffer讀取數(shù)據(jù)?
我們在Unity 2017.1上測試了一下,發(fā)現(xiàn)實際上在Android平臺的GLES調(diào)用中,Unity的Standard Shader的Opaque模式是在disable blend的狀態(tài)下渲染的,實驗如下:
設(shè)備:紅米2。渲染場景是兩個Standard Shader Opaque模式物體(Sphere和Cube),中間有一個Unlit Transparent的Quad:
通過Android工具查看GLES API調(diào)用發(fā)現(xiàn),每一幀渲染Cube和Sphere的時候Blend都是關(guān)閉狀態(tài)(上一幀結(jié)束時關(guān)掉),然后在渲染Unlit Transparent的Quad時打開:
其中,36個頂點的DC是渲染Cube,2304個頂點的DC是渲染Sphere,6個頂點的 DC是渲染quad。所以看起來Standard Shader的Opaque模式應(yīng)該是glDisable(GL_BLEND)的狀態(tài)下渲染的。
該問題來自UWA問答社區(qū),如您對該問題仍有疑問,可以轉(zhuǎn)至社區(qū)進(jìn)行進(jìn)一步交流。
https://answer.uwa4d.com/question/5a1a8e710aef30913881b489
內(nèi)存
Q4:在游戲每次打完副本回到主界面后,內(nèi)存數(shù)據(jù)總是不太一致,其中通過Unity Profiler我觀察到ManagedHeap.ReservedUnuseSize和ManagedHeap.UseSize的數(shù)值一直在變化,請問這個變化是否是合理的?
ReservedUnuseSize和ManagedHeap.UseSize一直在變化是正常的,它們都屬于Mono內(nèi)存,前者是當(dāng)前Mono內(nèi)存中沒有使用的,后者是正在使用的。一般游戲中,Mono堆內(nèi)存是會經(jīng)常由代碼來進(jìn)行分配的,所以這兩個值一直在變化,也是很正常的情況。
這里建議題主密切關(guān)注以下兩點:
(1)Mono的總堆內(nèi)存是否一直在升高
下圖是UWA性能測評報告中的Mono堆內(nèi)存走勢圖,其中的紫色線條即為項目運行時的ManagedHeap.UseSize,而黃色線條為ReservedUnuseSize,這兩者都是在變化的,但最需要關(guān)心的是藍(lán)色線條Reserved Mono,這條線條如果持續(xù)往上走,那么就說明項目中是很可能出現(xiàn)了內(nèi)存泄露問題,需要研發(fā)團(tuán)隊徹查,建議通過Mono詳細(xì)堆內(nèi)存分析來進(jìn)行修復(fù)。
(2)具體的堆內(nèi)存分配是否合理
ManagedHeap.UseSize或者M(jìn)ono總內(nèi)存的上升都是由于代碼的堆內(nèi)存產(chǎn)生的,所以查看代碼堆內(nèi)存分配是否合理,避免不必要的堆內(nèi)存分配是非常重要的,類似于下圖。
建議題主參考以下兩篇文章:
- 用正確的方式,三天搞定Mono堆內(nèi)存泄漏!
- Unity游戲的代碼堆內(nèi)存優(yōu)化
原文出處:侑虎科技
本文作者:admin
轉(zhuǎn)載請與作者聯(lián)系,同時請務(wù)必標(biāo)明文章原始出處和原文鏈接及本聲明。
總結(jié)
以上是生活随笔為你收集整理的技术分享连载(八十九)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 优化就是在和时间赛跑
- 下一篇: jfinal-swagger让你的应用接