国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

夢織網(wǎng)站短視頻seo推廣

夢織網(wǎng)站,短視頻seo推廣,企業(yè)網(wǎng)站建設(shè)和運(yùn)營,wordpress 代碼編輯插件內(nèi)存(Memory) unity 內(nèi)存部分也是優(yōu)化過程中非常重要的一個(gè)環(huán)節(jié),也會(huì)影像渲染過程中的同步等待與帶寬問題。因此內(nèi)存的優(yōu)化也可能會(huì)給我們渲染開銷帶來精簡,今天我們先來了解unity中的內(nèi)存與使用到的內(nèi)存工具。 Unity中的內(nèi)存 托…

內(nèi)存(Memory)

unity 內(nèi)存部分也是優(yōu)化過程中非常重要的一個(gè)環(huán)節(jié),也會(huì)影像渲染過程中的同步等待與帶寬問題。因此內(nèi)存的優(yōu)化也可能會(huì)給我們渲染開銷帶來精簡,今天我們先來了解unity中的內(nèi)存與使用到的內(nèi)存工具。

Unity中的內(nèi)存

  • 托管內(nèi)存:主要是指使用托管堆或者垃圾收集器自動(dòng)分配和管理的內(nèi)存也包括腳本堆棧與虛擬機(jī)內(nèi)存。
  • C#非托管內(nèi)存:可以在C#與Unity Collection名字空間和包結(jié)合使用,不使用垃圾收集器管理的內(nèi)存部分。如果使用數(shù)據(jù)結(jié)構(gòu),不建議使用system下的collection的數(shù)據(jù)結(jié)構(gòu),而是要使用unity collection下的數(shù)據(jù)結(jié)構(gòu)進(jìn)行開發(fā)。
  • Native 內(nèi)存:Unity 用于運(yùn)行引擎的C++內(nèi)存。

性能分析工具

下面我們聊一聊unity引擎提供了哪兒些內(nèi)存方面的工具

  1. Unity Profiler下的Memory標(biāo)簽:這里顯示了unity當(dāng)下內(nèi)存使用的追蹤狀態(tài),包括各類內(nèi)存的分配和使用情況,以及當(dāng)前unity下分配的對(duì)象與資源占用的內(nèi)存情況。2021以后版本,profiler不再提供對(duì)象抓取快照功能了。而是使用memory profiler 直接抓取內(nèi)存快照了。
  2. Memory Profiler:我們可以通過它來抓取內(nèi)存快照,也可以對(duì)比兩個(gè)內(nèi)存快照下unity對(duì)象與資源的差異。通過Tree Map來查看內(nèi)存分配的視圖。通過Object and Allocation標(biāo)簽查看具體對(duì)象內(nèi)存快照,并可以通過鏈接直接找到原工程中對(duì)應(yīng)的資源和對(duì)象,通過fragmentation標(biāo)簽可以查看內(nèi)存片段,unity2022以后 memory profiler變得更加簡潔了,針對(duì)native內(nèi)存甚至可以查看到具體是分配到哪兒個(gè)allocators中的。
  3. Memory Settings中的設(shè)置:大家現(xiàn)在可以在權(quán)衡時(shí)間和空間維度上的性能指標(biāo)做更精準(zhǔn)的設(shè)置了。
  4. UPR中的內(nèi)存快照功能:主要是針對(duì)移動(dòng)設(shè)備,當(dāng)你使用UPR做性能調(diào)試時(shí)會(huì)經(jīng)常用到,它可以脫離unity編輯器,在運(yùn)行時(shí)抓取內(nèi)存信息與對(duì)象分配信息,并可以做到多幀對(duì)比。具體操作請(qǐng)參閱UPR手冊(cè),后期我們可能會(huì)單獨(dú)做寫一個(gè)帖子,純翻譯供大家閱讀。
  5. mac或者ios上我們可以選擇xcode提供的instrument下的allocation工具。
  6. android上可以使用android相關(guān)的系統(tǒng)命令或者android studio profiler工具。
Profiler-Memory

Total Memory Breakdown(總內(nèi)存分解)

  • ManagedHeap:托管堆,重點(diǎn)監(jiān)控對(duì)象,不要讓它超過20MB,否則可能會(huì)有性能問題!
  • Graphics & Graphics Driver:驅(qū)動(dòng)程序在紋理、渲染目標(biāo)、著色器和網(wǎng)格數(shù)據(jù)上使用的估計(jì)內(nèi)存量。
  • Audio:音效及聲音文件,重點(diǎn)優(yōu)化對(duì)象,播放時(shí)長較長的音樂文件需要進(jìn)行壓縮成.mp3或.ogg格式,時(shí)長較短的音效文件可以使用.wav 或.aiff格式。
  • Video:視頻系統(tǒng)的估計(jì)內(nèi)存使用量。
  • Other:顯示Unity跟蹤的本機(jī)內(nèi)存,但不在特定計(jì)數(shù)器下報(bào)告。
  • Profiler:探查器功能從系統(tǒng)中使用和保留的內(nèi)存。

Objects Status(對(duì)象狀態(tài),顯示通常占用大量內(nèi)存的資源類型(紋理,網(wǎng)格,材質(zhì),動(dòng)畫剪輯)的對(duì)象實(shí)例數(shù)量,以及它們?cè)趦?nèi)存中的累積大小(資源,游戲?qū)ο?#xff0c;場景對(duì)象))

  • Texture2D: 2D貼圖及紋理。重點(diǎn)優(yōu)化對(duì)象,有以下幾點(diǎn)可以優(yōu)化:

    1.許多貼圖采用的Format格式是ARGB 32 bit所以保真度很高但占用的內(nèi)存也很大。在不失真的前提下,適當(dāng)壓縮貼圖,使用ARGB 16 bit就會(huì)減少一倍,如果繼續(xù)Android采用RGBA Compressed ETC2 8 bits(iOS采用RGBA Compressed PVRTC 4 bits),又可以再減少一倍。把不需要透貼但有alpha通道的貼圖,全都轉(zhuǎn)換格式Android:RGB Compressed ETC 4 bits,iOS:RGB Compressed PVRTC 4 bits。

    2.當(dāng)加載一個(gè)新的Prefab或貼圖,不及時(shí)回收,它就會(huì)永駐在內(nèi)存中,就算切換場景也不會(huì)銷毀。應(yīng)該確定物體不再使用或長時(shí)間不使用就先把物體制空(null),然后調(diào)用Resources.UnloadUnusedAssets(),才能真正釋放內(nèi)存。

    3.有大量空白的圖集貼圖,可以用TexturePacker等工具進(jìn)行優(yōu)化或考慮合并到其他圖集中。

    4.存在空白的或者純色的貼圖,可以用顏色節(jié)點(diǎn)代替

  • Mesh:場景中使用的網(wǎng)格模型,注意網(wǎng)格模型的點(diǎn)面數(shù),能合并的mesh盡量合并。
  • Materials:加載的材質(zhì)和它們使用的內(nèi)存的總數(shù)。
  • AnimationClip: 加載的動(dòng)畫和它們使用的內(nèi)存的總數(shù)。

Assets(已加載資產(chǎn)的總數(shù))

  • Game Objects:游戲?qū)ο罂倲?shù)
  • Scene Objects:這個(gè)數(shù)字包括游戲?qū)ο蟮臄?shù)量,加上組件的總數(shù),以及場景中所有不屬于資產(chǎn)的東西。
  • GC allocated in frame:顯示選定幀中托管分配的數(shù)量及其總大小(以字節(jié)為單位)。

Memory Profiler

主要用來查看托管內(nèi)存和本機(jī)內(nèi)存的詳細(xì)分配情況。它通過捕獲、檢查、比對(duì)內(nèi)存快照的方式來檢測內(nèi)存泄漏和內(nèi)存碎片。本篇文章中使用的版本是0.7.1版本。

安裝

add PackageManager- >Add By Name- >輸入com.unity.memoryprofiler?

查看

Windows - > Analysis - > Memory Profiler

Memory Profiler界面,可以鏈接真機(jī)檢測,也可以在Editor檢測。

點(diǎn)擊Capture? New Snapshot截取保存當(dāng)下幀的內(nèi)容

點(diǎn)擊上圖中3號(hào)的位置Snap來查看詳細(xì)的內(nèi)容

通過觀察,我們能看到上圖的數(shù)據(jù)與Profiler中的Memory的數(shù)據(jù)是一致的

單幀檢測

一般去看工程內(nèi)的資源, 去檢查占用內(nèi)存特別大的游戲?qū)ο蟆?/p>

Memory Breakdowns界面可以查看unity內(nèi)的具體游戲?qū)ο?#xff0c;也同樣可以進(jìn)行篩選

TreeMap界面進(jìn)行檢查, 這里已經(jīng)分好類, 同時(shí)可以根據(jù)Size的大小進(jìn)行排序,查看內(nèi)存占用較大的游戲?qū)ο筮M(jìn)行優(yōu)化處理。

Fragmentation 頁簽進(jìn)行查看, 點(diǎn)擊對(duì)應(yīng)的地址塊,下方可顯示詳細(xì)信息。

1.該視圖會(huì)將內(nèi)存數(shù)據(jù)可視化成虛擬內(nèi)存布局。如下圖所示:

?2.每一行都會(huì)顯示一個(gè)內(nèi)存塊和起始地址標(biāo)簽。當(dāng)起始地址標(biāo)簽上面有黑色背景時(shí),就表明該起始地址就是內(nèi)存塊的開始部分,并且與之前的內(nèi)存塊之間存在不連續(xù)性;否則,就表明該起始地址就是內(nèi)存塊的一部分。如下圖所示:

3.既可以通過單擊起始地址標(biāo)簽來選擇關(guān)聯(lián)的內(nèi)存塊;也可以通過單擊鼠標(biāo)拖動(dòng)的方式來選擇感興趣的內(nèi)存塊;甚至可以通過單擊內(nèi)存塊中的虛擬內(nèi)存來選擇該內(nèi)存塊。

4.當(dāng)選擇內(nèi)存塊時(shí),就會(huì)在Filters面板中將相關(guān)的虛擬內(nèi)存按照指定的列表類型(區(qū)域列表-Regions list、分配列表-Allocations list、對(duì)象列表-Objects list)進(jìn)行展示詳細(xì)信息。

區(qū)域列表類型展示信息如下圖所示:

分配列表類型展示信息如下圖所示:

還有對(duì)象列表類型展示信息,操作同上。

Objects and Allocations頁面可查看詳細(xì)的對(duì)比內(nèi)容,可以進(jìn)行篩選

篩選方式:Select Table View

篩選之后就可以進(jìn)行詳細(xì)分析了,可以通過Type,Size,?Referenced By等標(biāo)簽查看對(duì)應(yīng)的游戲?qū)ο蟆?/p>

也可以鼠標(biāo)右鍵點(diǎn)擊下圖1或者2來對(duì)類型和名字進(jìn)行具體篩選。

兩幀對(duì)比檢測

一般使用兩幀率對(duì)比用于檢測內(nèi)存泄漏。

在要對(duì)比的節(jié)點(diǎn)分別進(jìn)行Capture? New Snapshot截取, 點(diǎn)擊Compare Snapshots進(jìn)行對(duì)比,在分別點(diǎn)擊兩個(gè)Snap,進(jìn)行對(duì)比。

Summary頁簽可看匯總的對(duì)比內(nèi)容:

Objects and Allocations頁面可查看詳細(xì)的對(duì)比內(nèi)容,可以進(jìn)行篩選

篩選方式:Select Table View來查看以下幾種類型數(shù)據(jù):

  • [Diff] Raw Data:從原始數(shù)據(jù)列表中選擇一項(xiàng)原始數(shù)據(jù)(Root Reference、Native Allocation、Native Object等)進(jìn)行查看。
  • [Diff] All Managed Objects:查看所有的托管對(duì)象(IL2CPP、Mono)。
  • [Diff] All Native Objects:查看所有繼承自Unity.Object類型的本機(jī)對(duì)象。
  • [Diff] All Objects:查看所有本機(jī)對(duì)象和托管對(duì)象。
  • [Diff] Alloc:從分配列表中選擇一項(xiàng)分配數(shù)據(jù)(ByNativeObject、ByRoot、ByMemRegion)進(jìn)行查看。

篩選之后就可以進(jìn)行詳細(xì)分析了,可以通過Type,Size,?Referenced By等標(biāo)簽查看對(duì)應(yīng)的游戲?qū)ο蟆?/p>

也可以鼠標(biāo)右鍵來對(duì)類型和名字進(jìn)行具體篩選。

總結(jié)

MemoryProfiler 是一個(gè)非常好用的檢查內(nèi)存問題的工具,以下問題都可以通過該工具進(jìn)行排查

  • 查找有問題的游戲資源,例如:Mesh和貼圖非常大的美術(shù)資源
  • 內(nèi)存泄漏問題

檢測內(nèi)存占用:可以使用Unity Memory Profiler來檢測托管內(nèi)存和本機(jī)內(nèi)存的占用情況。檢測流程如下所示:

  1. 首先打開Unity Memory Profiler窗口;然后打開想要檢查的內(nèi)存快照;最后在主視圖區(qū)域以樹形視圖的方式來顯示內(nèi)存快照中深度內(nèi)存數(shù)據(jù)。
  2. 查看樹形視圖中不同的對(duì)象類別。
  3. 單擊樹形視圖中某一個(gè)對(duì)象類別,此時(shí)會(huì)展開該對(duì)象類別中所有的對(duì)象以及在主視圖區(qū)域下方以對(duì)象表格的方式來顯示該對(duì)象類別中所有的對(duì)象。
  4. 單擊對(duì)象類別中某一個(gè)對(duì)象或者單擊對(duì)象表格中某一個(gè)對(duì)象,進(jìn)而可以在對(duì)象表格中查看該對(duì)象的具體信息。
  5. 首先將對(duì)象表格中所有的對(duì)象按照從高到低的順序進(jìn)行排序;然后優(yōu)先從紋理、著色器變體、預(yù)分配緩沖區(qū)這三種對(duì)象來制定好減少內(nèi)存的目標(biāo)。

檢測內(nèi)存泄漏:可以使用Unity Memory Profiler來檢測托管內(nèi)存和本機(jī)內(nèi)存的泄漏情況。如下所示:
1.出現(xiàn)內(nèi)存泄漏的危害如下所示:

  • 應(yīng)用程序可能因?yàn)镚C遍歷對(duì)象時(shí)間變長的原因而出現(xiàn)卡頓現(xiàn)象。
  • 應(yīng)用程序可能因?yàn)榭捎脙?nèi)存空間不足的原因而出現(xiàn)閃退現(xiàn)象。

2.出現(xiàn)內(nèi)存泄漏的原因如下所示:

  • 對(duì)于自動(dòng)垃圾回收而言,對(duì)象的引用計(jì)數(shù)不為0。
  • 對(duì)于被動(dòng)垃圾回收而言,對(duì)象沒有被代碼手動(dòng)釋放。

3.查找并修復(fù)場景卸載后發(fā)生的內(nèi)存泄漏:流程如下所示:

  1. 使用Unity Memory Profiler來設(shè)置捕獲目標(biāo)。
  2. 首先在捕獲目標(biāo)上加載一個(gè)空?qǐng)鼍?#xff1b;然后在該場景上拍攝一張內(nèi)存快照。
  3. 首先在捕獲目標(biāo)上加載一個(gè)要檢測內(nèi)存泄漏的場景;然后在該場景上執(zhí)行業(yè)務(wù)模塊;最后將該場景卸載(調(diào)用Resources.UnloadUnusedAssets函數(shù))掉或者切換到一個(gè)空?qǐng)鼍啊?/li>
  4. 在捕獲目標(biāo)上再拍攝一張內(nèi)存快照。
  5. 為了避免處理內(nèi)存快照文件和捕獲目標(biāo)之間競爭系統(tǒng)資源,建議此時(shí)關(guān)閉掉捕獲目標(biāo)。
  6. 首先在工作臺(tái)區(qū)域打開第一張和第二張內(nèi)存快照文件;然后單擊Diff按鈕來對(duì)兩個(gè)打開的內(nèi)存快照進(jìn)行差異比對(duì);最后將差異比對(duì)生成的數(shù)據(jù)顯示在主視圖區(qū)域中。
  7. 首先在主視圖區(qū)域中選擇Diff表格屬性;然后選擇Group排序規(guī)則來將相同值(Deleted、New、Same)的對(duì)象合并在一個(gè)組內(nèi);最后查看數(shù)值為New的分組,如果存在對(duì)象是在第二張內(nèi)存快照中的話,就表明該對(duì)象的內(nèi)存泄漏了。

4.查找并修復(fù)小的連續(xù)分配可能造成的內(nèi)存泄漏:流程如下所示:

  1. 使用Unity Memory Profiler來設(shè)置捕獲目標(biāo)。
  2. 首先在捕獲目標(biāo)上加載一個(gè)要檢測內(nèi)存泄漏的場景;然后在該場景上拍攝第一張內(nèi)存快照。
  3. 首先播放要檢測內(nèi)存泄漏的場景;接著在該場景上拍攝第二張內(nèi)存快照;然后繼續(xù)播放該場景;最后在該場景上拍攝第三張內(nèi)存快照。
  4. 為了避免處理內(nèi)存快照文件和捕獲目標(biāo)之間競爭系統(tǒng)資源,建議此時(shí)關(guān)閉掉捕獲目標(biāo)。
  5. 首先在工作臺(tái)區(qū)域打開拍攝的第二張和第三張內(nèi)存快照文件;然后單擊Diff按鈕來對(duì)兩個(gè)打開的內(nèi)存快照進(jìn)行差異比對(duì);最后將差異比對(duì)生成的數(shù)據(jù)顯示在主視圖區(qū)域中。
  6. 首先在主視圖區(qū)域中選擇Diff表格屬性;然后選擇Group排序規(guī)則來將相同值(Deleted、New、Same)的對(duì)象合并在一個(gè)組內(nèi)。
  7. 首先在主視圖中選擇Owned Size表格屬性;然后選擇Group和Sort Descending排序規(guī)則來將相同值的對(duì)象合并在一個(gè)組內(nèi),并按照從大到小的順序來排列組。
  8. 查看較大內(nèi)存分配組中的對(duì)象是否同時(shí)存在于Same組和New組中,記錄好滿足條件的對(duì)象。
  9. 首先在工作臺(tái)區(qū)域打開拍攝的第一張和第二張內(nèi)存快照文件;接著單擊Diff按鈕來對(duì)兩個(gè)打開的內(nèi)存快照進(jìn)行差異比對(duì);然后將差異比對(duì)生成的數(shù)據(jù)顯示在主視圖區(qū)域中;最后執(zhí)行4.6 ~ 4.8步驟,進(jìn)而了解系統(tǒng)內(nèi)潛在的內(nèi)存泄漏。

元數(shù)據(jù):如下所示:
1.元數(shù)據(jù)類型為MetaData,包含的字段如下所示:

  1. content:包含項(xiàng)目名稱和捕獲目標(biāo)為Unity Editor時(shí)的腳本版本。
  2. platform:應(yīng)用程序?qū)?yīng)的目標(biāo)平臺(tái)。
  3. screenshot:針對(duì)捕獲目標(biāo)截取的屏幕截圖(像素大小小于480x240)。

2.首先在捕獲目標(biāo)上拍攝內(nèi)存快照時(shí)就會(huì)生成元數(shù)據(jù);然后該元數(shù)據(jù)會(huì)自動(dòng)添加到內(nèi)存快照中;最后開發(fā)人員可以通過元數(shù)據(jù)來更好地了解內(nèi)存快照的內(nèi)容。
3.拍攝內(nèi)存快照的方式如下所示:

  1. 當(dāng)項(xiàng)目中有安裝Unity Memory Profiler時(shí),此時(shí)就可以在工具欄區(qū)域中點(diǎn)擊Capture控件來針對(duì)捕獲目標(biāo)來拍攝一張內(nèi)存快照。
  2. 在代碼中通過MemoryProfiler.TakeSnapshot/TakeTempSnapshot函數(shù)來針對(duì)捕獲目標(biāo)拍攝一張內(nèi)存快照。在調(diào)用該函數(shù)時(shí),可以設(shè)置包含內(nèi)存快照文件路徑字符串和是否拍攝成功布爾值兩個(gè)參數(shù)的結(jié)束回調(diào)函數(shù)。

4.生成元數(shù)據(jù)的方式如下所示:

  1. 當(dāng)項(xiàng)目中沒有安裝Unity Memory Profiler時(shí),此時(shí)可以首先給MemoryProfiler.createMetaData委托注冊(cè)一個(gè)監(jiān)聽函數(shù);然后在該監(jiān)聽函數(shù)中設(shè)置元數(shù)據(jù)。
  2. 當(dāng)項(xiàng)目中有安裝Unity Memory Profiler時(shí),此時(shí)就會(huì)生成默認(rèn)的元數(shù)據(jù)。
  3. 當(dāng)項(xiàng)目中有安裝Unity Memory Profiler時(shí),此時(shí)就可以首先創(chuàng)建一個(gè)繼承自MetadataCollect類型的元數(shù)據(jù)收集類型;然后在該類型里面重寫CollectMetadata函數(shù);最后在該函數(shù)中設(shè)置元數(shù)據(jù)。

項(xiàng)目中可能遇到的問題

首先要明確一點(diǎn),在Editor中運(yùn)行時(shí),“Unity”大是正常的,因?yàn)樵贓ditor中運(yùn)行項(xiàng)目時(shí),引擎包含了所有的資源占用的內(nèi)存(除了部分紋理和Mesh是在GFX中),同時(shí)自身會(huì)進(jìn)行很多的輔助操作來記錄各種游戲運(yùn)行信息。一般來說,在查看游戲運(yùn)行時(shí)的真實(shí)消耗內(nèi)存,我們均是推薦直接在發(fā)布游戲上通過Profiler進(jìn)行查看,在Editor中運(yùn)行游戲所看到的內(nèi)存是要大很多的。


1.Device.Present:

  1. GPU的presentdevice確實(shí)非常耗時(shí),一般出現(xiàn)在使用了非常復(fù)雜的shader.
  2. GPU運(yùn)行的非???#xff0c;而由于Vsync的原因,使得它需要等待較長的時(shí)間.
  3. 同樣是Vsync的原因,但其他線程非常耗時(shí),所以導(dǎo)致該等待時(shí)間很長,比如:過量AssetBundle加載時(shí)容易出現(xiàn)該問題.
  4. Shader.CreateGPUProgram:Shader在runtime階段(非預(yù)加載)會(huì)出現(xiàn)卡頓(華為K3V2芯片).
  5. StackTraceUtility.PostprocessStacktrace()和StackTraceUtility.ExtractStackTrace(): 一般是由Debug.Log或類似API造成,游戲發(fā)布后需將Debug API進(jìn)行屏蔽。

2.Overhead:

  1. 一般情況為Vsync所致.
  2. 通常出現(xiàn)在Android設(shè)備上.

3.GC.Collect:

原因:

  1. 代碼分配內(nèi)存過量(惡性的)
  2. 一定時(shí)間間隔由系統(tǒng)調(diào)用(良性的).

占用時(shí)間:

  1. 與現(xiàn)有Garbage size相關(guān)
  2. 與剩余內(nèi)存使用顆粒相關(guān)(比如場景物件過多,利用率低的情況下,GC釋放后需要做內(nèi)存重排)

4.GarbageCollectAssetsProfile:

  1. 引擎在執(zhí)行UnloadUnusedAssets操作(該操作是比較耗時(shí)的,建議在切場景的時(shí)候進(jìn)行)。
  2. 盡可能地避免使用Unity內(nèi)建GUI,避免GUI.Repaint過渡GCAllow.
  3. if(other.tag == a.tag)改為other.CompareTag(a.tag).因?yàn)閛ther.tag為產(chǎn)生180B的GC Allow.
  4. 少用foreach,因?yàn)槊看蝔oreach為產(chǎn)生一個(gè)enumerator(約16B的內(nèi)存分配),盡量改為for.
  5. Lambda表達(dá)式,使用不當(dāng)會(huì)產(chǎn)生內(nèi)存泄漏.

5.盡量少用LINQ:

  1. 部分功能無法在某些平臺(tái)使用.
  2. 會(huì)分配大量GC Allow.

6.控制StartCoroutine的次數(shù):

  1. 開啟一個(gè)Coroutine(協(xié)程),至少分配37B的內(nèi)存.
  2. Coroutine類的實(shí)例 -> 21B.
  3. Enumerator -> 16B.

7.使用StringBuilder替代字符串直接連接.

8.緩存組件:

  1. 每次GetComponent均會(huì)分配一定的GC Allow.
  2. 每次Object.name都會(huì)分配39B的堆內(nèi)存.

9.ManagedHeap.UsedSize是項(xiàng)目邏輯代碼在運(yùn)行時(shí)申請(qǐng)的堆內(nèi)存,該選項(xiàng)只能通過優(yōu)化代碼來進(jìn)行降低。 優(yōu)化方法一般如下:

  1. 盡可能地復(fù)用變量,減少new的次數(shù);
  2. 使用StringBuilder代替String連接,使用for代替foreach;
  3. 對(duì)于局部變量或非常駐變量,盡可能使用Struct來代替Class。

ManagedHeap.UsedSize過大,一方面可能會(huì)影響一次GC的耗時(shí);另一方面也可能反映出腳本中不合理的GC Alloc。

10.有些小伙伴會(huì)發(fā)現(xiàn)System.ExecutableAndDlls占內(nèi)存巨大,且一直在增長,是怎么回事?

System.ExecutableAndDlls該項(xiàng)顯示的是執(zhí)行文件和所調(diào)用的庫(物理、渲染、IO等系統(tǒng)庫)的總和。開發(fā)團(tuán)隊(duì)不用太擔(dān)心該選項(xiàng)的數(shù)值,因?yàn)楹芏鄳?yīng)用均在共用這些庫,并且它對(duì)于真實(shí)項(xiàng)目的內(nèi)存壓力非常小,幾乎沒有影響,而且OS也不會(huì)因?yàn)樵搩?nèi)存而殺掉游戲或應(yīng)用。

11.凡是在Unity Profiler中能看到的資源就會(huì)保留在內(nèi)存中。對(duì)于這種資源,在切換場景時(shí)調(diào)一下UnloadUnusedAssets API就可以釋放。

12.Profiler.BeginSample統(tǒng)計(jì)到的數(shù)據(jù)與直接看Memory下的不一樣,前者比后者的數(shù)據(jù)更大,這怎么理解?

這種情況確實(shí)也是經(jīng)常會(huì)遇到的。一幀中分配如此高的內(nèi)存是會(huì)觸發(fā)GC.Collect的,而Mono中顯示的數(shù)值則是GC之后的Mono內(nèi)存數(shù)值。

13.正常情況下游戲如果一直玩下去,Mono是不是會(huì)一直增加? 比如頻繁打開一個(gè)界面,界面里有腳本會(huì)不斷創(chuàng)建一些東西 ,那么Mono是否會(huì)不斷增加?對(duì)性能上會(huì)不會(huì)造成影響呢?

在除開啟IL2CPP功能的應(yīng)用中,Mono 確實(shí)是不會(huì)下降,但并不應(yīng)該一直上升。
創(chuàng)建出來的東西,如果被引用在一個(gè)容器里,或者被某些腳本的變量引用,那么這部分堆內(nèi)存就釋放不掉;但如果沒有被任何容器或者變量引用(比如,臨時(shí)拼一個(gè) String),那么這部分堆內(nèi)存會(huì)在 GC 的時(shí)候釋放(釋放是指變?yōu)榭臻e的堆內(nèi)存,堆內(nèi)存的總量是不會(huì)下降的)。
對(duì)于后者,頻繁地 new 對(duì)象雖然不會(huì)一直增加堆內(nèi)存,但是會(huì)加速 GC 調(diào)用的頻率,所以同樣是需要盡量避免的。

14:我想請(qǐng)教一下,下圖這個(gè)函數(shù)中,每次我都申請(qǐng)了一個(gè)List temp = list();在這里存放6KB的數(shù)據(jù),但是如果不做GC處理,這6KB是否就一直累加,直到做GC處理了才會(huì)釋放掉,是這樣么?如果調(diào)用次數(shù)很多,每次都調(diào)用一點(diǎn)點(diǎn),也會(huì)推高內(nèi)存占用嗎?
請(qǐng)輸入圖片描述

是的,這個(gè)6KB堆內(nèi)存會(huì)隨著Update的執(zhí)行一直分配內(nèi)存,所累積的堆內(nèi)存會(huì)在GC觸發(fā)時(shí)進(jìn)行銷毀。一般來說,研發(fā)團(tuán)隊(duì)需要盡可能避免在高頻次調(diào)用函數(shù)中進(jìn)行堆內(nèi)存的分配。

15:在進(jìn)行內(nèi)存優(yōu)化時(shí),Unity Profiler給出的數(shù)據(jù)和Android系統(tǒng)(adb dumpsys meminfo,已經(jīng)考慮memtrack的影響 )的數(shù)據(jù)差距較大(已經(jīng)分析了Profiler自身的內(nèi)存占用),如何分析這部分差異,比如包括對(duì)顯存消耗進(jìn)行準(zhǔn)確統(tǒng)計(jì),OS消耗的統(tǒng)計(jì)等等?

內(nèi)存差異較大是正常的,一般來說,Profiler統(tǒng)計(jì)的內(nèi)存較為一致,而Android系統(tǒng)通過ADB反饋的PSS、Private Dirty等值則是差別很大。這主要是因?yàn)樾酒蚈S的不同而導(dǎo)致。具體的Android內(nèi)存,建議直接查看Google Android OS的相關(guān)文檔。
Unity Profiler反饋的則是引擎的真實(shí)物理使用內(nèi)存,一般我們都建議通過Profiler來查看內(nèi)存是否存在冗余、泄露等問題。

16:已經(jīng)預(yù)加載怪物,然后顯示怪物 PSS上升,并且在隱藏怪物后并沒有下降,這是什么原因?qū)е?#xff1f;顯存上去了嗎?

僅僅隱藏怪物的話,內(nèi)存是不會(huì)下降的。因?yàn)殡[藏只是改變了GameObject的狀態(tài),并沒有對(duì)內(nèi)存中的Object和資源進(jìn)行移除。同時(shí),即使是提前加載了怪物,也依然可能存在以上問題,因?yàn)槟承┵Y源是在顯示的時(shí)候,才會(huì)傳輸一份到GPU的,比如Mesh。一般情況下,顯存都不會(huì)即刻降低,這個(gè)是由Graphics Driver來管理的。建議可以看Profiler是否增長,如果Profiler沒有問題而PSS持續(xù)增長,就有可能發(fā)生了內(nèi)存泄露。

對(duì)于這個(gè)問題,建議查看《性能優(yōu)化,進(jìn)無止境---內(nèi)存篇(下)》加深理解。

17:對(duì)于Handheld.PlayFullScreenMovie 這個(gè)Unity播放開場動(dòng)畫的API,會(huì)有內(nèi)存問題嗎?比如我的mp4動(dòng)畫有20MB,那么這個(gè)動(dòng)畫會(huì)撐高mono堆內(nèi)存嗎?

Android上PlayFullScreenMovie 的實(shí)現(xiàn)實(shí)際上是通過Android原生的接口直接播放的,播放過程中Unity也是停止更新的,因此這部分的內(nèi)存理論上并不會(huì)記錄在 Unity 中,同樣也不影響Mono。

18:Texture占用內(nèi)存總是雙倍,這個(gè)是我們自己的問題,還是Unity引擎的機(jī)制?

出現(xiàn)這種情況的原因有兩種:一種是你在真機(jī)運(yùn)行時(shí)開啟了Read&Write。另一種可能是Unity的Bug,目前的Unity 5.2.3 release note如下 :
(735644) -?OpenGL: Fixed texture memory usage reporting in profiler, was twice the actual size for most textures.
開發(fā)者需要關(guān)注下自己的開發(fā)版本,5.2.3以前類似情況的項(xiàng)目可以參考一下。

19:如果腳本引用了GameObject,那轉(zhuǎn)換場景的時(shí)候腳本和GameObject都沒了,還會(huì)產(chǎn)生堆內(nèi)存的嗎?

如果腳本是MonoBehaviour,而且在切換場景后所掛的Game Object被釋放了,那么這個(gè)腳本對(duì)象所引用的堆內(nèi)存就會(huì)在GC的時(shí)候被釋放。 但有一種例外,如果是通過Static變量引用的堆內(nèi)存,那么依然是釋放不掉的,除非手動(dòng)解開引用,比如變量置Null,數(shù)組Clear等等。

移動(dòng)平臺(tái)內(nèi)存經(jīng)驗(yàn)數(shù)據(jù)參考

Textures:80M-160M

Mesh:50M-70M

Render Textures:50M-80M

AnimationClips:30M-60M

Audio:10M-20M

Cubemap:0-50M

Font:5M-15M

Shader:20M-40M

System.xxx總和:15M-30M

AssetBundle:0-10M

其他各類對(duì)象單項(xiàng):0-10M ,數(shù)量小于10000

ReservedMono:<100M

ReservedGFX:<300M

ReservedTotal:<650M

這些指標(biāo)的上下限分別代表了在移動(dòng)設(shè)備上的高低配數(shù)據(jù)的差異,其中Render Texture會(huì)根據(jù)目標(biāo)設(shè)備的分辨率的不同會(huì)有差異變化。這里給出的是1080P分辨率下的經(jīng)驗(yàn)數(shù)據(jù)指標(biāo)。一些下限為零的指標(biāo)為不使用此功能,可能沒有這方面的開銷數(shù)據(jù),如果各個(gè)指標(biāo)都在上述范圍內(nèi),不優(yōu)化也沒有問題。

移動(dòng)平臺(tái)其他經(jīng)驗(yàn)數(shù)據(jù)參考

DrawCall:300-600

SetPassCall:80-120

Triangles Count:60W-100W

Material Count:200-400

建議你的游戲相關(guān)指標(biāo)也控制在此范圍內(nèi),當(dāng)然數(shù)據(jù)僅供參考。

在我的文章里你可能會(huì)看到重復(fù)的內(nèi)容,原因是我的文章很多都是各路大神的心得,會(huì)有重復(fù)的,我沒有刪除,我覺得重復(fù)的多代表重要。

今天是2024年12月16日

重復(fù)一段毒雞湯來勉勵(lì)我和你

你的對(duì)手在看書

你的仇人在磨刀

你的閨蜜在減肥

隔壁的老王在練腰

而你在干嘛?

http://m.aloenet.com.cn/news/28962.html

相關(guān)文章:

  • 洞口做網(wǎng)站推廣信息怎么寫
  • 龍華高端網(wǎng)站設(shè)計(jì)愛站網(wǎng)關(guān)鍵詞查詢網(wǎng)站
  • 書畫網(wǎng)站 建設(shè)方案室內(nèi)設(shè)計(jì)培訓(xùn)
  • 各行各業(yè)網(wǎng)站建設(shè)獨(dú)立手機(jī)卡頓優(yōu)化軟件
  • 初中畢業(yè)想學(xué)動(dòng)漫專業(yè)抖音優(yōu)化排名
  • 厚街公司網(wǎng)站建設(shè)外貿(mào)營銷型網(wǎng)站建設(shè)公司
  • 濟(jì)南地產(chǎn)行業(yè)網(wǎng)站開發(fā)友情鏈接賺錢
  • 小程序外包公司發(fā)展前景百度sem優(yōu)化師
  • 網(wǎng)站開發(fā)流程可規(guī)劃為哪三個(gè)階段新手怎么做seo優(yōu)化
  • 做網(wǎng)站培訓(xùn)商品推廣軟文范例100字
  • 重慶市建設(shè)工程招標(biāo)投標(biāo)交易信息網(wǎng)山西seo基礎(chǔ)教程
  • 分布式wordpress網(wǎng)頁seo
  • 外國優(yōu)秀網(wǎng)站設(shè)計(jì)青島關(guān)鍵詞優(yōu)化平臺(tái)
  • 網(wǎng)站建設(shè)做什么百度收錄查詢工具
  • 互聯(lián)網(wǎng) 政府門戶網(wǎng)站建設(shè)方案最新國際新聞50條簡短
  • 網(wǎng)站后期維護(hù)費(fèi)用邯鄲seo營銷
  • 做黃色網(wǎng)站怎么賺錢精準(zhǔn)防控高效處置
  • 價(jià)格劃算的東莞建網(wǎng)站公司優(yōu)化營商環(huán)境評(píng)價(jià)
  • 東莞物流公司張家界seo
  • 江蘇 做網(wǎng)站推廣目標(biāo)怎么寫
  • 國外電商網(wǎng)站如何做icp備案網(wǎng)頁seo是什么意思
  • 泵 品牌網(wǎng)站建設(shè)深圳網(wǎng)站建設(shè)系統(tǒng)
  • 情人節(jié)給女朋友做網(wǎng)站線上推廣軟件
  • 南京公司網(wǎng)站開發(fā)合肥瑤海區(qū)
  • 一個(gè)jsp做的購物小網(wǎng)站搜索引擎優(yōu)化的方法和技巧
  • wordpress文庫插件搜索引擎優(yōu)化的流程
  • wordpress裝在根目錄文件夾中_如何通過域名直接訪問?google關(guān)鍵詞seo
  • 四川省建筑設(shè)計(jì)院排名seo哪家公司好
  • 動(dòng)態(tài)網(wǎng)站數(shù)據(jù)庫設(shè)計(jì)seo搜索引擎優(yōu)化排名哪家更專業(yè)
  • 在網(wǎng)上如何找做網(wǎng)站的人品牌營銷策略分析