1)子線程GC導(dǎo)致主線程函數(shù)耗時(shí)較高的問(wèn)題
2)升級(jí)Unity大版本后,Text顏色修改問(wèn)題
3)清除增量式GC導(dǎo)致的Mono堆內(nèi)存泄漏問(wèn)題
4)多Pass合批優(yōu)化問(wèn)題
這是第274篇UWA技術(shù)知識(shí)分享的推送乌助。今天我們繼續(xù)為大家精選了若干和開發(fā)渊胸、優(yōu)化相關(guān)的問(wèn)題吏口,建議閱讀時(shí)間10分鐘圈暗,認(rèn)真讀完必有收獲泽铛。
UWA 問(wèn)答社區(qū):answer.uwa4d.com
UWA QQ群2:793972859(原群已滿員)
Rendering
Q:在主線程中有非常多的卡頓病曾,從UWA的報(bào)告中看到很多異常的高耗時(shí)牍蜂,請(qǐng)問(wèn)可能是什么原因造成的?
A:像上面這樣的頻繁卡頓泰涂,且卡頓函數(shù)種類非常多的情況鲫竞,應(yīng)該是子線程分配了非常多的堆內(nèi)存,導(dǎo)致子線程GC逼蒙,從而卡住了主線程从绘。當(dāng)GC的時(shí)候,主線程可能會(huì)處于各種階段是牢,因此對(duì)應(yīng)階段的函數(shù)耗時(shí)就會(huì)包括等待GC的耗時(shí)僵井。可以從UWA的Mono報(bào)告中查看是否有子線程分配了大量的堆內(nèi)存驳棱,通常是由這種(Thread)打頭的子線程函數(shù)的分配導(dǎo)致的批什。
感謝han@UWA問(wèn)答社區(qū)提供了回答,歡迎大家轉(zhuǎn)至社區(qū)交流:
https://answer.uwa4d.com/question/6180e0f28f8c834241fd6930
UGUI
Q:從Unity 4.6.9f1升級(jí)到Unity 2020.3.2.f1c1社搅。首次Unity升級(jí)之后UI的Text顏色修改是正常驻债。當(dāng)運(yùn)行一次之后,所有的Text顏色都無(wú)法修改了形葬。就算新創(chuàng)建一個(gè)新的Text也無(wú)法修改合呐。
A:會(huì)有多余的UI-Default和UI-DefaultFont這兩個(gè)Shader,刪除它們笙以,然后重啟Unity就好了淌实。
感謝芝麻青豆角@UWA問(wèn)答社區(qū)提供了回答,歡迎大家轉(zhuǎn)至社區(qū)交流:
https://answer.uwa4d.com/question/6185085fd8413e18eb034520
Mono
Q:最近在研究Mono堆內(nèi)存時(shí),發(fā)現(xiàn)一幀內(nèi)分配多次較大內(nèi)存拆祈,會(huì)導(dǎo)致內(nèi)存無(wú)法被回收恨闪。
過(guò)程如下:
在同一幀內(nèi)調(diào)用三次分配100MB內(nèi)存的方法,分配內(nèi)存的變量都是在各自的作用域放坏,在這之后調(diào)用GC.Collect()凛剥。發(fā)現(xiàn)有較大幾率出現(xiàn)100MB或者200MB無(wú)法被回收的Mono堆內(nèi)存。經(jīng)過(guò)排查之后發(fā)現(xiàn)取消勾選Incremental GC之后轻姿,內(nèi)存就能完全被收回犁珠。
我推測(cè)是每次申請(qǐng)內(nèi)存的時(shí)候會(huì)執(zhí)行一次GC,清除上一次分配的內(nèi)存互亮,但是由于使用增量GC犁享,無(wú)法在本幀完成回收工作。再下一次GC的時(shí)候豹休,第二次GC的回收內(nèi)容被重置了炊昆,導(dǎo)致第二次的GC需要被回收的內(nèi)存就泄漏了。
不知道我這么理解是不是對(duì)的威根,希望大佬們解惑凤巨。同時(shí)希望大佬告知有沒(méi)有辦法清除這部分內(nèi)存。
測(cè)試環(huán)境:
Unity 2019.4.15c1
Unity 2020.4.15f2
測(cè)試平臺(tái):
安卓 Mono
以下為測(cè)試代碼:
A:通過(guò)題主的方法洛搀,我也復(fù)現(xiàn)了該問(wèn)題敢茁。我還是比較贊同你的理解的。
Unity官網(wǎng)的一篇關(guān)于增量GC的博客也寫了該方法的弊端:
它的正常運(yùn)行是需要前提的留美,那就是在GC期間這些被標(biāo)記為“需要清理的內(nèi)存”都保持不變彰檬。如果在GC期間變化了,比如頻繁分配大量?jī)?nèi)存谎砾,那么就需要重新標(biāo)記一遍逢倍,而這個(gè)階段可能會(huì)有意想不到的bug產(chǎn)生。內(nèi)存泄漏很可能就是發(fā)生在這個(gè)階段(我也只是猜測(cè))景图。
不過(guò)個(gè)人覺(jué)得增量GC仍然是一個(gè)良好的嘗試较雕,雖然它只是測(cè)試階段,也存在著一些問(wèn)題挚币,但是以前的Boehm-Demers-Weiser garbage collector很容易引起高耗時(shí)峰值從而造成卡頓亮蒋,而分代式GC正是為了減輕峰值的影響,盡量確保流暢性忘晤。
可以參考官方博客:https://blog.unity.com/technology/feature-preview-incremental-garbage-collection
該回答由UWA提供宛蚓,歡迎大家轉(zhuǎn)至社區(qū)交流:
https://answer.uwa4d.com/question/61658ad48f8c834241d92a0b
Rendering
Q:游戲使用簡(jiǎn)單的Mesh顯示幾十張撲克牌激捏,為了效果设塔,材質(zhì)Shader使用了2個(gè)Pass,其中一個(gè)是拉伸做邊緣效果,但是由于是多Pass闰蛔,即使是相同的材質(zhì)和貼圖痕钢,還是不能動(dòng)態(tài)合批,請(qǐng)教這種情況有沒(méi)有什么優(yōu)化方案序六?
1. 不能合批任连,但是材質(zhì)是相同的,順序渲染過(guò)程中是否有什么狀態(tài)切換的消耗例诀?
2. 能否使用兩個(gè)Mesh随抠,不同的材質(zhì),Shader都使用單Pass繁涂,區(qū)別是一個(gè)Mesh是正常顯示拱她,一個(gè)Mesh僅僅做拉伸邊緣效果,理論上是不是不超過(guò)頂點(diǎn)數(shù)的情況下可以兩次動(dòng)態(tài)合批扔罪?
A1:Unity BuiltIn渲染管線不支持多Pass合批秉沼,多Pass的Shader通過(guò)Set Pass call逐個(gè)渲染每個(gè)Pass后才會(huì)繼續(xù)渲染下一個(gè)Object重復(fù)一遍,所以會(huì)產(chǎn)生比較多的Draw Call矿酵。
更好的辦法就是用自定義的渲染管線的方式渲染多個(gè)Pass唬复。在渲染第一個(gè)Pass的時(shí)候,把所有的Object一次性全都渲染了全肮,渲染完畢之后通過(guò)一次Set Pass Call去渲染下個(gè)Pass敞咧,可以試下URP渲染管線。
感謝星傲蝶戀@UWA問(wèn)答社區(qū)提供了回答
A2:題主說(shuō)的第二點(diǎn)是比較常規(guī)的做法辜腺,要注意的是為了防止Draw Call的穿插妄均,需要調(diào)整這兩種渲染的RenderQueue,將他們對(duì)應(yīng)的RenderQueue錯(cuò)開哪自。
感謝Xuan@UWA問(wèn)答社區(qū)提供了回答丰包,歡迎大家轉(zhuǎn)至社區(qū)交流:
https://answer.uwa4d.com/question/6178c9c58f8c834241f2aaeb
20211108
更多精彩問(wèn)題等你回答~
Unity增量打包AssetBundle沒(méi)變化的資源也會(huì)被重新打包
在模型有UV2的情況下開啟Generate Lightmap UVs
封面圖來(lái)源于網(wǎng)絡(luò)
今天的分享就到這里。當(dāng)然壤巷,生有涯而知無(wú)涯邑彪。在漫漫的開發(fā)周期中,您看到的這些問(wèn)題也許都只是冰山一角胧华,我們?cè)缫言赨WA問(wèn)答網(wǎng)站上準(zhǔn)備了更多的技術(shù)話題等你一起來(lái)探索和分享寄症。歡迎熱愛(ài)進(jìn)步的你加入,也許你的方法恰能解別人的燃眉之急矩动;而他山之“石”有巧,也能攻你之“玉”。
官網(wǎng):www.uwa4d.com
官方技術(shù)博客:blog.uwa4d.com
官方問(wèn)答社區(qū):answer.uwa4d.com
UWA學(xué)堂:edu.uwa4d.com
官方技術(shù)QQ群:793972859(原群已滿員)