IOS效能調優系列:使用Instruments動態分析記憶體洩漏,調優instruments
第一篇介紹了Analyze對App做靜態分析,可以發現應用中的記憶體洩漏問題,對於有些記憶體洩漏情況通過靜態分析無法解決的,可以通過動態分析來發現,分析起來更有針對性。
從本篇開始介紹XCode提供的強大的分析工具Instruments,記憶體分析只是Instruments中的一個功能,其他功能後續介紹。
使用Instruments動態分析記憶體洩漏
Instruments中的Leaks功能主要用於分析記憶體洩漏,還是以《IOS效能調優系列:Analyze靜態分析》裡記憶體洩漏的例子還實驗:
1 //擷取部分影象 2 +(UIImage*)getSubImage:(unsigned long)ulUserHeader 3 { 4 UIImage * sourceImage = [UIImage imageNamed:@"header.png"]; 5 CGFloat height = sourceImage.size.height; 6 CGRect rect = CGRectMake(0 + ulUserHeader*height, 0, height, height); 7 8 CGImageRef imageRef = CGImageCreateWithImageInRect([sourceImage CGImage], rect); 9 UIImage* smallImage = [UIImage imageWithCGImage:imageRef]; 10 //CGImageRelease(imageRef); 11 12 return smallImage; 13 }
用註釋註釋掉CGImageRelease(imageRef)這行,即使在ARC開啟的環境下,仍然會導致記憶體洩漏(Arc is only for NSObject)。
使用Leaks開始動態分析,點選XCode的Product選單Profile啟動Instruments:
選擇Leaks,會自動啟動Leaks工具和IOS模擬器:
Leaks啟動後會開始錄製,隨著對模擬器執行的App的操作,可以在Leaks中檢視記憶體佔用的情況。
注:如果你的專案使用了ARC,隨著你的操作,不斷開啟或關閉檢視,記憶體可能持續上升,但這不一定表示存在記憶體洩漏,ARC釋放的時機是不固定的。
Leaks頂部分為兩欄:Allocations和Leaks,右側的曲線代表記憶體分配和記憶體洩漏曲線。
點選第二欄Leaks,進行記憶體洩漏分析,左下角會出現Leaks除錯的選項:
建議把Snapshot Interval間隔時間設定為10秒,勾選Automatic Snapshotting,Leaks會自動進行記憶體捕捉分析。
在你懷疑有記憶體洩漏的操作前和操作後,可以點選Snapshot Now進行手動捕捉。
以下是切換到我的App中呼叫 +(UIImage*)getSubImage:(unsigned long)ulUserHeader 函式的檢視,可以發現記憶體洩漏:
Leaked Object的表格中顯示了記憶體洩漏的型別、數量及記憶體空間。
點選具體的某個記憶體洩漏物件,在右側Detail視窗中會出現導致洩漏可能的位置,其中黑色頭像代表了最可能的位置。
Leaks已成功找出了[CMTool getSubImage:]這個函式:
記憶體洩漏動態分析技巧
熟練使用Leaks後會對記憶體洩漏判斷更準確,在可能導致洩漏的操作裡,多使用Snapshot Now手動捕捉。
開始時如果裝置效能較好,可以把自動捕捉間隔設定為5秒鐘。
使用ARC的專案,一般記憶體洩漏都是malloc、自定義結構、資源引起的,多注意這些地方進行分析。
開啟ARC後,記憶體洩漏的原因
開啟了ARC並不是就不會存在記憶體問題,蘋果有句名言:ARC is only for NSObject。
在IOS 中使用malloc分配的記憶體,ARC是不會處理的,需要自己進行處理。
例子中的 CGImageRef 也是一個Image的指標,ARC也不會進行處理。
記錄,為更好的自己!