国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

刨根問底U3D---從Profile中窺探Unity的內存管理

2019-11-17 02:35:58
字體:
來源:轉載
供稿:網友

刨根問底U3D---從PRofile中窺探Unity的內存管理

這篇文章包含哪些內容

這篇文章從Unity的Profile組件入手,來探討一下Unity在開發(fā)環(huán)境和正式環(huán)境中的內存使用發(fā)面的一些區(qū)別,

并且給出了最好控制內存的方法(我想你已經知道了...Prefab ) ,以及原因。

提前需要閱讀的文章

在閱讀本文之前或之后我建議閱讀一下以下幾篇文章

雨松的

Unity3D研究院之Assetbundle的實戰(zhàn)http://www.xuanyusong.com/archives/2405/

Unity3D研究院之Assetbundle的原理http://www.xuanyusong.com/archives/2373

王巍的

Unity 3D中的內存管理http://onevcat.com/2012/11/memory-in-unity3d/

星塵(不太確定是否是原作者 哈)的

Unity3D占用內存太大的解決方法http://m.survivalescaperooms.com/88999660/archive/2013/03/15/2961663.html


從NGUI的Altaspacker說起

事情的起因還是因為我在學習使用NGUI(剛接觸Unity沒幾天…), 教程看了看都沒問題 自己動手操作的時候突然發(fā)現(xiàn)...

NGUI 創(chuàng)建UI時候必須都先要創(chuàng)建Altas,那我創(chuàng)建好后的散圖是放在工程里面呢 還是要刪掉? 不刪會影響性能么?

Google了一番并沒有發(fā)現(xiàn)滿意答案,所以只好自己Profile一下,于是有了如下實驗:

1· 首先建立一個空場景,運行,打開Profile. Texture(紋理)部分使用內存2.5MB

2·加入一張圖片,場景上不做任何引用。 該圖片顯存展開后大小為1.5MB , 運行 然后再打開Profile

3· 奇跡的事情發(fā)生了... 紋理占用的內存大小直接變?yōu)?5.8MB

5.8MB- 2.5MB = 3.3MB 很奇怪的一個數(shù),于是我同時懷疑三件事

1· 即使素材完全用不到但是如果工程中有導入則最后會被打包

2· 即使素材沒有被當前場景使用,Unity仍舊會加載 ( Unity啟動時候加載所有的素材??! )

3· Unity對素材在內存中有留有一份引用,3.3MB ~= 1.5MBx2 ( ??! )

如果以上三點有一個是真的(全是錯的), 那Unity無疑直接變?yōu)閺U柴....

于是乎就此三點我開始無限的刨根問底....

功夫不負有心人吧,終于在一片帖子上面找到了突破口

http://answers.unity3d.com/questions/57909/find-unused-assets-in-project.html

這篇文章說的很清楚,Unity在發(fā)布時候會自動過濾掉未引用的所有資源,并且整個被打包進來的資源可以通過Log查看

根據文章指出的位置找到Log,并且就上面的工程進行測試,打出Android包 (Mac下Log在 /Users/eran/Library/Logs/Unity/Editor.log , eran為你的用戶名)

這樣的話 第一個心結就解開了, 看來Unity果真沒有這么傻... 以后使用NGUI制作Atlas時候也不用擔心是否需要刪除小圖這件事了.

既然知道了只有在真機設備上才可以進行測試,于是需要再將剛才做的測試重來一次了,只不過這次是在真機上面.

1· 首先建立一個空場景,運行,打開Profile. Texture(紋理)部分使用內存153.0KB

可以注意到,在真機上面運行時候 內存占用明顯降低了,并且開銷的線很平,不再像編輯環(huán)境一樣會有波動.

2·加入一張圖片并放置在場景上面

雖然沒有像想象中的那樣為1.5MB,不過 既然小于3MB,則Unity3D肯定不可能留有一份內存的備份(DRAM一份 VRAM一份,DRAM的用于處理LostConext時候重新上傳GPU).

這里面其實還有一個小插曲:

在Android上面 Rendering中顯示 使用的顯存為0,這點和我理解的3D渲染原理不符呀,一直讓我困惑了很久。后來突然想到 難道是因為手機是共享顯存的原因?

果不其然 當我把項目發(fā)布為PC版本時候再跑Profile,顯存占用就有數(shù)字了. 并且顯存占用數(shù)和我后面說道的動態(tài)剔除還有關系,說明顯存還發(fā)生了swap,這塊和所講的事情無關 就不細說了,如果大神對這塊很了解 希望指點我一下.

ok 繼續(xù)說上面提到一嘴的 動態(tài)剔除,這個是我無意發(fā)現(xiàn)的,

我把上面那張圖加了一個Animation 讓其左右移動,當我真機測試時候,當這張圖片移出屏幕時候DrawCall會減1,也就是只要屏幕看不到的東西Unity會自動幫你剔除,

減少DrawCall, 其實細想想, 這個是很正常的一個事情,因為Unity是一個完全的3D引擎,這也是為什么在Unity里面沒有像素 進來單位是Unit,沒有屏幕的寬高,只能調整攝像機的視野.

相比之下之前用的Starling,Cocos,雖然底層也在使用GPU進行渲染,但是他的整體引擎架構是基于2D的,所以自然無法在底層完成這種自動剔除以及顯存交換的行為.相比之下Unity要優(yōu)越許多.

就此Unity的一大謎題得以解開,根據上面的實驗我得到了如下兩條結論

結論: 即使項目中有許多未使用的圖片,只要未放置在特殊文件夾下(Resource,StreamingAssets)并且沒有被Prefab引用,最終導出時候不會被打包,更不會占用顯存,但是在開發(fā)階段會.

結論: Unity 會自行對移出場景的對象進行剔除從而減少DrawCall


Prefab 最好的管理內存(顯存)的方式

我的刨根問底行為到這里并沒有結束, 既然知道了Unity如何加載素材,那他什么時候卸載呢?

我又做了如下實驗:

建立兩個場景,SceneA,SceneB. 在SceneA中加載一張紋理,同時提供一個跳轉到SceneB的按鈕.

點擊按鈕跳轉到SceneB,SceneB是一個空場景 什么都不放.

預期的是當切換到SceneB時候SceneA中所占用的顯存應該會被釋放,不過結果卻又是讓人大失所望... 仍舊沒有變化

即使我在SceneB中調用GC都沒用(其實看過GC介紹的朋友也應該知道在那里調GC本來就應該沒用)

最后又是一通Google,不過這次沒有像上次那么走運 沒有任何的收獲,這也是我后來轉向開始研究Prefab的原因. 不過還是繼續(xù)把這里說完.

又是一次意外的測試,我發(fā)現(xiàn)當我再建立一個SceneC時候, 由SceneA->SceneB->SceneC 這個時候 SceneA中的顯存會得到釋放. 就此問題我還發(fā)了一個Question.

有個朋友給了他項目上的證實,Unity確實如此http://ask.unitymanual.com/question/36097

既然Unity自動管理的內存需要跨兩個場景才能消除,那我們有沒有辦法自己控制呢? 方法是有的 那就是使用Prefab.

如何創(chuàng)建及如何使用Prefab 松雨的那兩篇文章已經說的非常明白了,我就不重復造輪子了.

結論: Unity自身的顯存回收是需要經過跨兩個場景,如果使用Prefab在調用assetBundle.Unload (true)時候可以釋放顯存。

以上是我這幾天通過實驗摸索的一些經驗,希望能對你有所幫助。如果哪里說的不對還請大神指出

謝謝

Best

Eran


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 新龙县| 侯马市| 嘉峪关市| 上犹县| 兰州市| 深泽县| 盐边县| 三穗县| 广元市| 高邮市| 蒙山县| 临安市| 驻马店市| 贡嘎县| 滁州市| 额敏县| 罗城| 馆陶县| 阿克| 梨树县| 蚌埠市| 华坪县| 类乌齐县| 灵台县| 达州市| 都江堰市| 陆良县| 阆中市| 桦川县| 辛集市| 永仁县| 繁峙县| 姚安县| 高碑店市| 天等县| 新和县| 克拉玛依市| 新乐市| 广河县| 来安县| 荃湾区|