溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Perfdog玩轉內存泄漏

發(fā)布時間:2020-08-07 04:48:29 來源:ITPUB博客 閱讀:166 作者:騰訊WeTest 欄目:互聯網科技

背景交代

最近QC同學在跑游戲的過程中發(fā)現玩的時間久了游戲會發(fā)生閃退,經過搜集信息后排除了功能性bug的

一.判斷是否是內存泄露

拿到真機,USB連接,殺掉多余后臺進程,打開Perfdog,接下來一頓操作猛如虎,Perfdog具體操作不在贅述,有關perfdog怎么使用的教程可以參考

Perfdog使用教程

拿到內存趨勢圖

使用手機

Perfdog玩轉內存泄漏

Perfdog玩轉內存泄漏

此圖一出,基本就可以斷定內存泄露了,這是正常玩游戲,游戲運行了30分鐘的內存趨勢圖;

結論:,內存持續(xù)上升,存在內存泄露。

一個優(yōu)秀的游戲通常情況內存是有上升有回落,多次運行同一個功能也不會導致內存功能持續(xù)上升;

呈現出起伏狀態(tài),比如:

Perfdog玩轉內存泄漏

知道了存在內存泄露,下面就要開始分析有可能是哪里導致的內存泄露;

二.分析泄露原因

一般針對unity游戲來說,內存瓶頸是資源和Mono堆內存,兩部分;

以下是unity游戲程序在運行時的內存分配概況

Perfdog玩轉內存泄漏

先簡單介紹下Mono,unity使用Mono機制來完成跨平臺的操作,就好像JAVA使用虛擬機來完成跨平臺操作一樣,Mono也是一種跨平臺的實現??缙脚_其實現原理在于使用了叫CIL(Common Intermediate Language通用中間語言,也叫做MSIL微軟中間語言)的一種代碼指令集,CIL可以在任何支持CLI(通用語言基礎結構)的環(huán)境中運行,就像.NET是微軟對這一標準的實現,Mono則是對CLI的又一實現。由于CIL能運行在所有支持CLI的環(huán)境中,例如剛剛提到的.NET運行時以及Mono運行時,也就是說和具體的平臺或者CPU無關。

一般對于unity開發(fā)的游戲來說,內存的開銷都是圍繞下面的三個方面:

1.資源內存的占用;

2.引擎模塊自身內存占用;

3.托管堆內存占用。

Mono通過垃圾回收機制(GarbageCollect,簡稱GC)對內存進行管理,可以自動地改變堆的大小來適應你所需要的內存,并且是可以適時地調用垃圾回收(GarbageCollection)操作來釋放已經不需要的內存。也就是說Mono會自動釋放一些內存,但要注意的是GC釋放的內存只會留給mono使用,并不會交還給操作系統(tǒng),因此mono堆內存是只增不減的。

這里簡單介紹下Mono回收原理:

Mono會跟蹤每次內存分配的動作,并維護一個分配對象表,當GC的時候,以全局數據區(qū)和當前寄存器中的對象為根節(jié)點,按照引用關系進行遍歷,對于遍歷到的每一個對象,將其標記為活的(alive)。所有對象的被標記意味著該對象可以通過全局對象或者當前上下文訪問到,而沒有被標記的對象則意味著該對象無法通過任何途徑訪問到,即該對象“失聯”了,GC最終會將所有“失聯”的對象內存進行回收。

內存泄露定義

我們把對象已經不再需要使用卻沒有被GC回收的情況稱為mono內存泄漏。Mono內存泄漏會使空閑內存減少,GC頻繁,mono堆不斷擴充,最終導致游戲內存占用的升高。最終導致內存過高,進程被操作系統(tǒng)Kill或者崩潰。簡單來說,也就是一些對象被實例化出來后沒有被釋放掉,一種保存在內存中,新的對象又需要申請新的內存空間,導致內存不斷上升。

重點關注點

配置文件的使用、紋理、網格、RenderTexture和粒子系統(tǒng);

比如頻繁的創(chuàng)建銷毀對象是否使用對象池,或者粒子,紋理等資源顯示過后是否被及時從內存中釋放,等等;

三.測試手段

1.首先通跑測試,確定問題確定原因,比如我上面通過通跑游戲確定存在內存泄露;

2.縮小范圍,由于一個游戲在運行的過程中場景比較復雜,上面的同跑并不能準確定位問題,所以我們要劃分場景測試,例如我在上面的通跑游戲過程中包括以下場景,打開關閉UI界面,戰(zhàn)斗場景,切換地圖,升級武器等,如果沒有比較明顯的數據,那就要分別針對以下場景進行測試。比如UI場景可以反復打開關閉UI界面,戰(zhàn)斗場景可以持續(xù)戰(zhàn)斗掛機,反復切換地圖等等,總之是把游戲內進行的行為減少,細化要檢測的場景;

Perfdog玩轉內存泄漏

3.定位問題

如果某個場景發(fā)生內存泄露,邊定位到那個場景運行游戲,而在游戲運行時,相應的引擎也有一些工具可以查看具體的代碼使用情況,比如unity的Profiler。

如果多個場景都出現內存泄露,那就要查找這些場景所交叉的部分,比如通信框架等;而本次經過多個場景的測試發(fā)現都存在泄露,最后經過排查發(fā)現是使用的通信框架存在泄露問題。

四,Perfdog內存相關簡介

通常情況下安卓可以輕松獲取到的內存有4種數據,我們也可以通過ADB來獲取,

VSS - Virtual Set Size 虛擬耗用內存(包含共享庫占用的內存)

RSS - Resident Set Size 實際使用物理內存(包含共享庫占用的內存)

PSS - Proportional Set Size 實際使用的物理內存(比例分配共享庫占用的內存)

USS - Unique Set Size 進程獨自占用的物理內存(不包含共享庫占用的內存)

一般來說內存占用大小有如下規(guī)律:VSS >= RSS >= PSS >= USS

而Perfog的Memory也就是 Android PSS Memory,也是我們通常來用作代表內存的數據,是實際使用的物理內存大小。

Swap Memory (Swap Memory,部分設備支持Swap功能,在啟用Swap功能后,系統(tǒng)會對PSS內存進行壓縮,Swap增加,PSS會相應減少,由于壓縮會占用CPU資源,同時相應會導致FPS降低)

Virtual Memory(VSS) 虛擬內存是計算機系統(tǒng)內存管理的一種技術。它使得應用程序認為它擁有連續(xù)的可用的內存(一個連續(xù)完整的地址空間),而實際上它通常是被分隔成多個物理內存碎片,還有部分暫時存儲在外部磁盤存儲器上,在需要時進行數據交換。

五、Perfdog新功能初探

PerfDog 3.5版本剛剛推出,新增一個最新的數值,CPU Usage(Normalized):規(guī)范化CPU利用率

官方給出的解釋為:

傳統(tǒng)計算方法:當前時刻CPU頻率下,CPU Usage = CPU執(zhí)行時間/CPU總時間。

由于移動設備CPU頻率時刻變化,用傳統(tǒng)CPU利用率計算方法,假定在低頻率時刻計算出CPU利用率=30%,和在CPU高頻時刻計算出CPU利用率=30%。同樣都是30%但性能消耗是完全不樣的,明顯高頻消耗更高。傳統(tǒng)CPU利用率已無法真實反映性能消耗。

所以我們需要一種規(guī)范化(可量化)的統(tǒng)計方式。將頻率因素考慮進去。

CPU Usage(Normalized)= (CPU執(zhí)行時間/CPU總時間) * (當前時刻所有CPU頻率之和/所有CPU頻率最大值之和)。

PerfDog兩種統(tǒng)計方式都有。CPU Usage默認為規(guī)范化CPU利用率。建議使用規(guī)范化CPU利用率作為衡量性能指標。

具體的描述可以看這里: 規(guī)范化CPU利用率

嘗鮮體驗以下。測試使用過程和之前的一樣。來看看新增的數據對比

title:

Perfdog玩轉內存泄漏

CPU Usage趨勢圖對比:

Perfdog玩轉內存泄漏

CPU Core Usage趨勢圖對比:

Perfdog玩轉內存泄漏

從趨勢圖來看的話,實際上兩種算法并無太大差異,但是精確到具體幀的使用率,差異會比較明顯,單純從性能的角度來說,傳統(tǒng)CPU利用率僅能從數值的角度體現手機的CPU使用程度,但是無法從性能使用程度的角度表達手機的CPU使用效率,就像前文所說,低頻率時刻計算出CPU利用率=30%,和在CPU高頻時刻計算出CPU利用率=30%。同樣都是30%但性能消耗是完全不樣的。規(guī)范化CPU利用率數值可以彌補這一缺點。目前的測試行業(yè)良莠不齊,規(guī)范指標較少,如果真的可以做到統(tǒng)一行業(yè)標準不失為一件好事。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI