Unity手遊iOS記憶體分析和測試
測試目標
保證1G記憶體的iOS裝置(iPhone 6、iPhone 6 Plus等)可在長時間持續遊戲不閃退,同時優化已知的記憶體佔用過高問題。
測試分析
由於已知遊戲記憶體佔用過高,針對這一問題,要搭建測試環境,模擬玩家的實際操作以及外網的實際情況,測試記憶體的使用情況。一般分為基礎測試、壓力測試和其他測試。
1.基礎測試,即各種基本操作測試,比如場景切換操作、UI介面操作等;
2.壓力測試,即多角色操作測試,比如角色的載入、角色的複雜程度、技能和動作的釋放、上線下線操作等等,比如模擬多角色野外場景壓力測試等;
3.其他測試,比如Xcode的相關工具使用分析等;
在測試中統計各操作對記憶體增長的貢獻,分析可能的原因,並基於測試結果提出合理的優化方案。
測試思路
基礎測試
對於基礎測試這一部分,可做的測試較多,我們僅拿UI介面操作測試和場景切換測試為例。
1. UI介面操作測試
主角進入指定場景的固定位置,儘量重複操作所有能操作的UI介面,取樣對比前後的記憶體增長。
測試結果:
對比兩次取樣結果,單純的介面操作行為,記憶體總共增長了140M,其中增長最多的是UITexture,剩餘的主要是AnimationClip、AnimatorController和其他Texture等。
測試結果分析:
為何UITexture介面貼圖會佔用這麼多的記憶體呢?
經分析,為了解決Android平臺下開啟介面響應過慢的問題,我們對UI介面採用了快取機制。但是在iOS平臺下,首先iPhone的反應速度要優於Android;其次iOS平臺(如iPhone 6記憶體只有1G的裝置)對應用程式的記憶體使用佔比控制比Android平臺更為嚴格,超過一定閥值系統會自動結束該程式。因此在iOS平臺下,速度與記憶體要兼顧,儘可能節約對記憶體的使用。
針對這個問題可以修改介面快取策略:
1.根據介面優先順序、重要性進行劃分,擇優快取;
2.部分大圖集拆小、允許少量小貼圖元素冗餘;
在後續的優化中,程式修改了介面快取策略,單純UITexture方面就減少了約80M!如果你的專案也有這方面的需求,非常值得一試哦!
2. 場景切換測試
指定A場景的一個固定位置,主角從A場景切換到B場景,然後從B場景切換到A場景,重複切換多次後,最終回到A場景的固定位置,取樣對比前後的記憶體增長。
測試結果:
對比場景切換前後的記憶體使用情況,發現無明顯的變化。
測試結果分析:
場景切換前後記憶體無增長,基本保證了切換場景邏輯無記憶體洩露。反之,在測試中如果記憶體增加較多,則需要檢視程式碼邏輯修復問題。
壓力測試
對於壓力測試這一部分,由於情況比較多,操作比較複雜,所以要仔細測試。
為何要模擬外網真實環境進行測試呢?
首先就是可能無外網真實環境可用,這個沒有辦法,只能模擬;其次是外網真實環境過於複雜不利於有效的分析;再次就是外網真實環境不能隨時重現利用,並長時間供測試人員分析,所以要儘量去模擬外網環境。
我們就以模擬多角色野外場景壓力測試為例,進行迭代優化。由於需要模擬多人PK的情景,所以我們自己製作了機器人來方便定位並分析多人情況下的效能和記憶體問題。
1. 模擬多角色野外場景壓力測試
模擬測試場景一:
選中一個野外場景A,主角和大量隨機門派、隨機外觀的機器人進入場景,隨機釋放技能,然後機器人全部下線。分不同情況採集資料對比記憶體增長,在機器人全部下線後,主角切換到場景B,再切回測試場景A的原始位置,採集資料對比記憶體增長。
測試結果:
機器人上線後各種不同場景下的內容變化情況如下:
機器人靜止時,記憶體對比空場景,增長97.5M;
機器人釋放技能平穩後,記憶體對比空場景,增長119.4M;
機器人全部下線,記憶體對比空場景,依然增長98.3M;
機器人全部下線後,主角切換場景,再切回測試場景,記憶體對比空場景,基本無增長。
測試結果分析:
通過上述的測試及結果,結果分析及可獲得的資訊如下:
1.機器人全部下線後,由於大部分資源進入快取池,故記憶體有增長是正常的;
2.機器人全部下線並切換場景後,對比空場景基本無增長,說明快取池已全部解除安裝,故切換場景的快取池釋放邏輯正確、無洩漏;
3.角色相關的絕大部分資源儲存至快取池,切換場景後,所有進入快取池的資源全部解除安裝,這一過程看似合理,但存在風險隱患:單場景記憶體峰值存在過高的風險。
單場景記憶體峰值存在過高的風險,究竟會有多高、快取池到底有無洩露呢?
我們來進一步優化當前的測試環境:既然資源會進快取池,那麼我們放大它的影響,讓資源不斷進出快取池。複雜化我們的測試場景,增加機器人不斷上下線操作。
2. 模擬多角色野外場景壓力測試 2.0
模擬測試場景二:
迭代優化“模擬測試場景一”,選中一個野外場景A,主角和大量隨機門派、隨機外觀的機器人進入場景,在隨機時間點,機器人不斷的上下線,線上期間隨機釋放技能,每隔五分鐘取樣資料。
測試結果:
a. 取樣資料:
13min 後遊戲閃退。
b. 資料截圖:
5:15:37資料截圖
5:20:55資料截圖
5:25:02資料截圖
測試結果分析:
Material、AnimatorOverrideController、Mesh均在持續增長,我們的快取池存在嚴重的資源洩露。剩下的問題就是解決洩露啦,相信我們程式GG,一定可以快速解決問題的!
在解決洩露問題後,我們的記憶體就真的沒問題了嗎?
我們需要進一步驗證結果。在“多角色測試場景二”的基礎上,我們還可以做些什麼呢?和外網玩家實際情況相比,我們是不是還欠缺了一些東西呢?是的,比如頻繁的聊天、UI介面操作、在地圖內跑動等,再次複雜化測試場景。
3. 模擬多角色野外場景壓力測試 3.0
模擬測試場景三:
迭代優化“模擬測試場景二”,選中一個野外場景A,主角和大量隨機門派、隨機外觀的機器人進入場景,在隨機時間點,機器人不斷的上下線,線上期間隨機釋放技能、不停喊話,主角在野外場景中繞地圖兩圈後,選擇固定點站立不動,用低配手機開到遊戲內的最高配置,掛機半小時後,儘量重複操作可操作UI介面後,繼續掛機半小時以上,間隔一定時間採集資料。
測試結果:
全程無閃退,記憶體峰值不超標。
測試結果分析:
為何要用低配手機開高配模式去測試呢?
因為外網玩家的環境總比我們內部模擬的環境要複雜的多,所以要儘可能以高標準要求整個遊戲的質量。
為何要繞地圖兩週呢?
因為繞地圖兩週後,地圖大部分資源就會進入快取池中,記憶體會上升。
為何要掛機半小時後再去重複操作可操作的UI介面呢?
因為地圖資源和角色資源該進快取池的資源基本都進去了,再去操作UI介面,才是真正的記憶體壓力瓶頸,可以撐過這個記憶體瓶頸,才能基本保證記憶體方面基本無重大問題。
這樣複雜的測試環境下,低配手機若可以保證連續執行一個小時以上無閃退,記憶體峰值不超標,就基本保證了遊戲記憶體方面無重大問題了。至此,該測試環境就可以作為釋出版本前,必做的客戶端記憶體壓測案例之一了。
其他測試
Unity手遊需要做優化的東西非常非常多,而記憶體測試僅是其中的一個方向。本文所舉案例中的大部分都可以用Unity自帶的Profiler或外掛進行測試,但這隻能針對Unity自身可以抓取到的資源進行分析。若要分析整體記憶體的詳細情況則需使用Xcode的相關工具。
1.通過Debug Navigator來觀察App的Memory、CPU、FPS等整體情況;
2.通過Leaks分析記憶體洩漏;
3.通過AllocationsInstruments來收集所有的分配資訊,比如:第三方庫或服務的分配情況、蘋果圖形硬體驅動部分 (視訊記憶體共享);Lua VM 分配和管理部分等。
Allocations Instruments收集所有的分配資訊後,我們就可以針對分配次數多和分配尺寸大的模組進一步優化。同時,還需關注分配效率,因為分配得過於零碎,會導致利用率不高,往往還沒有達到記憶體閥值就已經閃退了。
此外,還有一個便捷的途徑,就是請UWA的專業團隊來幫忙給專案做全方位的優化,包括效能診斷與優化、資源檢測與分析等。該團隊為我們專案做過優化,專業、細緻、深入,整個過程收益頗多,有需求的團隊不妨一試!
鑑於此次的優化記憶體使用的經驗與教訓,作為測試人員,一定要認真細緻地制定測試步驟並嚴格執行,善於從各種資料中理清頭緒並定位出問題根本原因,以優化目標為導向,以當前的測試結果為修正值,不斷地迭代優化測試環境,這樣才能保證效能測試結果的正確性、發現專案中存在的嚴重問題、給出合理的優化方案及建議並最終保證遊戲的質量。
以上的測試及觀點,不免有遺漏或者不周、不妥的地方,歡迎拍磚、批評指正!
相關文章
- Unity效能分析(三)記憶體分析Unity記憶體
- Unity Memory Profiler 記憶體分析Unity記憶體
- 【小松教你手遊開發】【unity實用技能】unity 記憶體除錯方法Unity記憶體除錯
- 遊戲記憶體測試遊戲記憶體
- 主要測試記憶體和資料庫記憶體資料庫
- Weex-iOS 記憶體分析iOS記憶體
- Color類和測試記憶體的類MemoryMonitor記憶體
- iOS檢測記憶體洩漏iOS記憶體
- 軟體測試學習教程——WEB測試之JS記憶體WebJS記憶體
- DDR記憶體基礎知識和頻寬測試記憶體
- 如何讓手遊記憶體佔用更小?從記憶體消耗iOS實時統計開始記憶體iOS
- Android記憶體優化——記憶體洩露檢測分析方法Android優化記憶體洩露
- UE 手遊在 iOS 平臺執行時記憶體佔用太高?試試這樣著手優化iOS記憶體優化
- 理解 iOS 和 macOS 的記憶體管理iOSMac記憶體
- Linux記憶體洩露案例分析和記憶體管理分享Linux記憶體洩露
- iOS 記憶體管理iOS記憶體
- iOS 記憶體洩漏排查方法及原因分析iOS記憶體
- 在iOS上自動檢測記憶體洩露iOS記憶體洩露
- Android記憶體測試方法梳理和實現原理簡析Android記憶體
- Unity開發者的C#記憶體管理UnityC#記憶體
- MongoDB記憶體使用分析和優化MongoDB記憶體優化
- 記憶體洩漏測試小工具 - LeakDiag記憶體
- 記憶體分析與記憶體洩漏定位記憶體
- “理解”iOS記憶體管理iOS記憶體
- iOS 記憶體管理MRCiOS記憶體
- iOS 記憶體管理研究iOS記憶體
- 探索iOS記憶體分配iOS記憶體
- iOS記憶體淺談iOS記憶體
- iOS arc 記憶體管理iOS記憶體
- Ubuntu記憶體分析Ubuntu記憶體
- JVM記憶體分析JVM記憶體
- MLeaksFinder:精準 iOS 記憶體洩露檢測工具iOS記憶體洩露
- iOS記憶體洩漏自動檢測工具PLeakSnifferiOS記憶體
- 實體記憶體和虛擬記憶體記憶體
- iOS記憶體管理和malloc原始碼解讀iOS記憶體原始碼
- Unity記憶體最佳化(來自uwa)Unity記憶體
- 關於redis記憶體分析,記憶體優化Redis記憶體優化
- 分析記憶體洩漏和goroutine洩漏記憶體Go