遊戲記憶體測試
背景交代
最近QC同學在跑遊戲的過程中發現玩的時間久了遊戲會發生閃退,經過蒐集資訊後排除了功能性bug的
一.判斷是否是記憶體洩露
拿到真機,USB連線,殺掉多餘後臺程式,開啟Perfdog,接下來一頓操作猛如虎,Perfdog具體操作不在贅述,有關perfdog怎麼使用的教程可以參考
Perfdog使用教程
拿到記憶體趨勢圖
使用手機
此圖一出,基本就可以斷定記憶體洩露了,這是正常玩遊戲,遊戲執行了30分鐘的記憶體趨勢圖;
結論:,記憶體持續上升,存在記憶體洩露。
一個優秀的遊戲通常情況記憶體是有上升有回落,多次執行同一個功能也不會導致記憶體功能持續上升;
呈現出起伏狀態,比如:
知道了存在記憶體洩露,下面就要開始分析有可能是哪裡導致的記憶體洩露;
二.分析洩露原因
一般針對unity遊戲來說,記憶體瓶頸是==資源==和==Mono==堆記憶體,兩部分;
以下是unity遊戲程式在執行時的記憶體分配概況
先簡單介紹下Mono,unity使用Mono機制來完成跨平臺的操作,就好像JAVA使用虛擬機器來完成跨平臺操作一樣,Mono也是一種跨平臺的實現。跨平臺其實現原理在於使用了叫CIL(Common Intermediate Language通用中間語言,也叫做MSIL微軟中間語言)的一種程式碼指令集,CIL可以在任何支援CLI(通用語言基礎結構)的環境中執行,就像.NET是微軟對這一標準的實現,Mono則是對CLI的又一實現。由於CIL能執行在所有支援CLI的環境中,例如剛剛提到的.NET執行時以及Mono執行時,也就是說和具體的平臺或者CPU無關。
一般對於unity開發的遊戲來說,記憶體的開銷都是圍繞下面的三個方面:
1.資源記憶體的佔用;
2.引擎模組自身記憶體佔用;
3.託管堆記憶體佔用。
Mono通過垃圾回收機制(GarbageCollect,簡稱GC)對記憶體進行管理,可以自動地改變堆的大小來適應你所需要的記憶體,並且是可以適時地呼叫垃圾回收(GarbageCollection)操作來釋放已經不需要的記憶體。也就是說Mono會自動釋放一些記憶體,但要注意的是GC釋放的記憶體只會留給mono使用,並不會交還給作業系統,因此mono堆記憶體是隻增不減的。
這裡簡單介紹下Mono回收原理:
Mono會跟蹤每次記憶體分配的動作,並維護一個分配物件表,當GC的時候,以全域性資料區和當前暫存器中的物件為根節點,按照引用關係進行遍歷,對於遍歷到的每一個物件,將其標記為活的(alive)。所有物件的被標記意味著該物件可以通過全域性物件或者當前上下文訪問到,而沒有被標記的物件則意味著該物件無法通過任何途徑訪問到,即該物件“失聯”了,GC最終會將所有“失聯”的物件記憶體進行回收。
記憶體洩露定義
我們把物件已經不再需要使用卻沒有被GC回收的情況稱為mono記憶體洩漏。Mono記憶體洩漏會使空閒記憶體減少,GC頻繁,mono堆不斷擴充,最終導致遊戲記憶體佔用的升高。最終導致記憶體過高,程式被作業系統Kill或者崩潰。簡單來說,也就是一些物件被例項化出來後沒有被釋放掉,一種儲存在記憶體中,新的物件又需要申請新的記憶體空間,導致記憶體不斷上升。
重點關注點
配置檔案的使用、紋理、網格、RenderTexture和粒子系統;
比如頻繁的建立銷燬物件是否使用物件池,或者粒子,紋理等資源顯示過後是否被及時從記憶體中釋放,等等;
三.測試手段
1.首先通跑測試,確定問題確定原因,比如我上面通過通跑遊戲確定存在記憶體洩露;
2.縮小範圍,由於一個遊戲在執行的過程中場景比較複雜,上面的同跑並不能準確定位問題,所以我們要劃分場景測試,例如我在上面的通跑遊戲過程中包括以下場景,開啟關閉UI介面,戰鬥場景,切換地圖,升級武器等,如果沒有比較明顯的資料,那就要分別針對以下場景進行測試。比如UI場景可以反覆開啟關閉UI介面,戰鬥場景可以持續戰鬥掛機,反覆切換地圖等等,總之是把遊戲內進行的行為減少,細化要檢測的場景;
3.定位問題
如果某個場景發生記憶體洩露,邊定位到那個場景執行遊戲,而在遊戲執行時,相應的引擎也有一些工具可以檢視具體的程式碼使用情況,比如unity的Profiler。
如果多個場景都出現記憶體洩露,那就要查詢這些場景所交叉的部分,比如通訊框架等;而本次經過多個場景的測試發現都存在洩露,最後經過排查發現是使用的通訊框架存在洩露問題。
四,Perfdog記憶體相關簡介
通常情況下安卓可以輕鬆獲取到的記憶體有4種資料,我們也可以通過ADB來獲取,
VSS - Virtual Set Size 虛擬耗用記憶體(包含共享庫佔用的記憶體)
RSS - Resident Set Size 實際使用實體記憶體(包含共享庫佔用的記憶體)
PSS - Proportional Set Size 實際使用的實體記憶體(比例分配共享庫佔用的記憶體)
USS - Unique Set Size 程式獨自佔用的實體記憶體(不包含共享庫佔用的記憶體)
一般來說記憶體佔用大小有如下規律:VSS >= RSS >= PSS >= USS
而Perfog的Memory也就是 Android PSS Memory,也是我們通常來用作代表記憶體的資料,是實際使用的實體記憶體大小。
Swap Memory (Swap Memory,部分裝置支援Swap功能,在啟用Swap功能後,系統會對PSS記憶體進行壓縮,Swap增加,PSS會相應減少,由於壓縮會佔用CPU資源,同時相應會導致FPS降低)
Virtual Memory(VSS) 虛擬記憶體是計算機系統記憶體管理的一種技術。它使得應用程式認為它擁有連續的可用的記憶體(一個連續完整的地址空間),而實際上它通常是被分隔成多個實體記憶體碎片,還有部分暫時儲存在外部磁碟儲存器上,在需要時進行資料交換。
相關文章
- 遊戲記憶體對比普通記憶體區別 遊戲記憶體和普通記憶體相差大嗎?遊戲記憶體
- 軟體測試學習教程——WEB測試之JS記憶體WebJS記憶體
- 好玩又不佔記憶體的手遊 記憶體小又能聯機的傳奇遊戲記憶體遊戲
- win10遊戲記憶體不足怎麼辦_win10玩遊戲提示記憶體不足處理方法Win10遊戲記憶體
- 遊戲測試和軟體測試有什麼區別?遊戲
- 被記憶體溢位苦苦折磨的小測試!!!記憶體溢位
- mac系統記憶體測試工具:Micromat Lifespan for macMac記憶體
- 遊戲測試?遊戲營銷遊戲
- 遊戲&軟體測試到底是什麼?遊戲測試理論詳解來了!遊戲
- win10電腦記憶體測試軟體怎麼用_win10記憶體檢測工具的使用方法Win10記憶體
- Fedora 上的桌面環境記憶體佔用測試記憶體
- DDR記憶體基礎知識和頻寬測試記憶體
- Fuzzm: 針對WebAssembly記憶體錯誤的模糊測試Web記憶體
- 記憶體條頻率越高越好嗎?高低頻率DDR4記憶體條效能測試對比記憶體
- win10遊戲提示視訊記憶體不足如何處理 win10玩遊戲提示視訊記憶體不足怎麼解決Win10遊戲記憶體
- 【程式設計測試題】遊戲任務標記程式設計遊戲
- iOS檢測記憶體洩漏iOS記憶體
- 簡單VC記憶體檢測記憶體
- 軟體測試學習教程——過載new或delete來檢測記憶體洩漏delete記憶體
- 黑鯊遊戲手機Helo評測:全球首款10GB記憶體手機,為手遊而生!遊戲記憶體
- Redis記憶體——記憶體消耗(記憶體都去哪了?)Redis記憶體
- .netcore持續整合測試篇之搭建記憶體伺服器進行整合測試一NetCore記憶體伺服器
- 程式碼安全測試第十一期:記憶體洩漏漏洞記憶體
- 瞭解與軟體測試的區別,輕鬆應付遊戲測試遊戲
- 記憶體管理 記憶體管理概述記憶體
- 【記憶體管理】記憶體佈局記憶體
- 遊戲包體太大,記憶體不足?Unity貼圖壓縮注意這幾點遊戲記憶體Unity
- windows10系統使用自帶記憶體檢測工具檢測記憶體好壞的方法Windows記憶體
- php操作共享記憶體shmop類及簡單使用測試(程式碼)PHP記憶體
- 開發板中的記憶體壓力測試,你瞭解多少?記憶體
- 從密碼電池到記憶卡,承載記憶的載體,回憶那些年我們的遊戲存檔密碼遊戲
- 記憶體二三事: Xcode 記憶體圖、Instruments 視覺化檢測迴圈引用記憶體XCode視覺化
- 記一次對Java多執行緒記憶體可見性的測試Java執行緒記憶體
- 25年前,開發者如何將遊戲塞進記憶體?遊戲記憶體
- Java的記憶體 -JVM 記憶體管理Java記憶體JVM
- Go:記憶體管理與記憶體清理Go記憶體
- 聊聊 記憶體模型與記憶體序記憶體模型
- linux記憶體管理(一)實體記憶體的組織和記憶體分配Linux記憶體