硬廣:《IOS性能調(diào)優(yōu)系列》第二篇,持續(xù)更新,歡迎關(guān)注。
第一篇介紹了Analyze對(duì)App做靜態(tài)分析,可以發(fā)現(xiàn)應(yīng)用中的內(nèi)存泄漏問(wèn)題,對(duì)于有些內(nèi)存泄漏情況通過(guò)靜態(tài)分析無(wú)法解決的,可以通過(guò)動(dòng)態(tài)分析來(lái)發(fā)現(xiàn),分析起來(lái)更有針對(duì)性。
從本篇開(kāi)始介紹XCode提供的強(qiáng)大的分析工具Instruments,內(nèi)存分析只是Instruments中的一個(gè)功能,其他功能后續(xù)介紹。

使用Instruments動(dòng)態(tài)分析內(nèi)存泄漏
Instruments中的Leaks功能主要用于分析內(nèi)存泄漏,還是以《IOS性能調(diào)優(yōu)系列:Analyze靜態(tài)分析》里內(nèi)存泄漏的例子還實(shí)驗(yàn):
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)這行,即使在A(yíng)RC開(kāi)啟的環(huán)境下,仍然會(huì)導(dǎo)致內(nèi)存泄漏(Arc is only for NSObject)。
使用Leaks開(kāi)始動(dòng)態(tài)分析,點(diǎn)擊XCode的PRoduct菜單Profile啟動(dòng)Instruments:

選擇Leaks,會(huì)自動(dòng)啟動(dòng)Leaks工具和IOS模擬器:

Leaks啟動(dòng)后會(huì)開(kāi)始錄制,隨著對(duì)模擬器運(yùn)行的App的操作,可以在Leaks中查看內(nèi)存占用的情況。
注:如果你的項(xiàng)目使用了ARC,隨著你的操作,不斷開(kāi)啟或關(guān)閉視圖,內(nèi)存可能持續(xù)上升,但這不一定表示存在內(nèi)存泄漏,ARC釋放的時(shí)機(jī)是不固定的。
Leaks頂部分為兩欄:Allocations和Leaks,右側(cè)的曲線(xiàn)代表內(nèi)存分配和內(nèi)存泄漏曲線(xiàn)。

點(diǎn)擊第二欄Leaks,進(jìn)行內(nèi)存泄漏分析,左下角會(huì)出現(xiàn)Leaks調(diào)試的選項(xiàng):

建議把Snapshot Interval間隔時(shí)間設(shè)置為10秒,勾選Automatic Snapshotting,Leaks會(huì)自動(dòng)進(jìn)行內(nèi)存捕捉分析。
在你懷疑有內(nèi)存泄漏的操作前和操作后,可以點(diǎn)擊Snapshot Now進(jìn)行手動(dòng)捕捉。
以下是切換到我的App中調(diào)用 +(UIImage*)getSubImage:(unsigned long)ulUserHeader 函數(shù)的視圖,可以發(fā)現(xiàn)內(nèi)存泄漏:

Leaked Object的表格中顯示了內(nèi)存泄漏的類(lèi)型、數(shù)量及內(nèi)存空間。
點(diǎn)擊具體的某個(gè)內(nèi)存泄漏對(duì)象,在右側(cè)Detail窗口中會(huì)出現(xiàn)導(dǎo)致泄漏可能的位置,其中黑色頭像代表了最可能的位置。
Leaks已成功找出了[CMTool getSubImage:]這個(gè)函數(shù):

內(nèi)存泄漏動(dòng)態(tài)分析技巧
熟練使用Leaks后會(huì)對(duì)內(nèi)存泄漏判斷更準(zhǔn)確,在可能導(dǎo)致泄漏的操作里,多使用Snapshot Now手動(dòng)捕捉。
開(kāi)始時(shí)如果設(shè)備性能較好,可以把自動(dòng)捕捉間隔設(shè)置為5秒鐘。
使用ARC的項(xiàng)目,一般內(nèi)存泄漏都是malloc、自定義結(jié)構(gòu)、資源引起的,多注意這些地方進(jìn)行分析。
開(kāi)啟ARC后,內(nèi)存泄漏的原因
開(kāi)啟了ARC并不是就不會(huì)存在內(nèi)存問(wèn)題,蘋(píng)果有句名言:ARC is only for NSObject。
在IOS 中使用malloc分配的內(nèi)存,ARC是不會(huì)處理的,需要自己進(jìn)行處理。
例子中的 CGImageRef 也是一個(gè)Image的指針,ARC也不會(huì)進(jìn)行處理。
記錄,為更好的自己!
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注