iOS 內(nèi)存泄漏的查找

更多內(nèi)容請挪步我的博客

前言

最近為[伯樂在線]翻譯一篇文章(該文章尚未發(fā)布)流济,作者 Russ Bishop 談到自己查找內(nèi)存泄漏的一次痛苦經(jīng)歷,讀后很有感觸洁奈,但是那些對于 Instruments 使用不太熟練的讀者可能由于 Bishop 忽略了一些細(xì)節(jié)奈虾,看后估計(jì)會覺得喝白水般不能解渴仅孩,所以寫一篇自己的經(jīng)歷將 Bishop 忽略的細(xì)節(jié)補(bǔ)全作為“譯后感”吧。

一種麻煩的檢查內(nèi)存泄漏方式

為什么麻煩還要介紹呢碧磅,因?yàn)榭吹接腥诉@樣調(diào)試的碘箍。這種方式需要寫些代碼,這些代碼完全是調(diào)試用的鲸郊,而且只能讓你知道是否存在泄漏丰榴,但是無法定位,看看這種方式如何操作秆撮。

在 dealloc 方法中寫一個日志四濒,如果退出頁面的時候能夠打印出日志內(nèi)容,說明該頁面沒有問題职辨,如果沒有打印盗蟆,那么就是有問題的。

- (void)dealloc {
     DLog(@"release");
 }

這樣如果頁面中有輸出 release拨匆,說明該頁面 CollageViewController 是沒有內(nèi)存泄漏的

2016-04-01 12:51:56.992 [267:19048] -[CollageViewController dealloc] - [Line 88] -- release

但是如果故意把循環(huán)引用引入姆涩,這個時候會有 Warning 警告,同時 release 也不會打印了

self.paperSizeView.paperSizeBlock = ^(PaperSizeModel *sizeModel) {
    self.paperSize = sizeModel.paperSize;
}

要把 self 改為 WeakSelf惭每。

上面的 DLog 是我常用的一個日志宏骨饿,調(diào)試的時候能輸出函數(shù)名稱和所在行數(shù),定義如下

#ifdef DEBUG
#define DLog(args, ...) NSLog((@"%s - [Line %d] -- " args), __FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#   define DLog(...)
#endif

如果覺得這樣的方式輸入的內(nèi)容還不夠豐富台腥,建議使用 喵神的代碼

#define NSLog(format, ...) do { \
    fprintf(stderr, "<%s : %d> %s\n",  \
    [[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], \
    __LINE__, __func__);  \
   (NSLog)((format), ##__VA_ARGS__);   \
   fprintf(stderr, "-------\n");       \
} while (0)

注意宏赘,這種方式在某些情況下仍然能執(zhí)行 dealloc,并不是十分可靠黎侈,還要確認(rèn) Instruments 的 Leaks 下沒有報(bào)錯才可以察署,例如以下這種比較常見的循環(huán)引用,需要使用 Leaks 查看峻汉。

常見的循環(huán)引用

@interface RetainCycleModel : NSObject
@property (strong, nonatomic) id obj;
@end


RetainCycleModel *model1 = [[RetainCycleModel alloc] init];
RetainCycleModel *model2 = [[RetainCycleModel alloc] init];

[model1 setObj:model2];
[model2 setObj:model1];

上例中 model1 強(qiáng)引用了 model2贴汪,model2 又強(qiáng)引用了 model1脐往。Demo 代碼點(diǎn)擊這里

如何用 Instrument 定位隱蔽的循環(huán)引用

還是拿 [LEAF Photo] 舉例,運(yùn)行 Allocation扳埂。

運(yùn)行后业簿,將所有的頁面都跑一遍,會看到內(nèi)存一直增長阳懂,當(dāng)返回頁面后內(nèi)存應(yīng)該是下降趨勢的梅尤。如果內(nèi)存沒有返回到初始狀態(tài),說明在某個頁面是有內(nèi)存泄漏的岩调。這時可以在搜索框搜索自己寫的類名巷燥。

leak1.jpg

看,這是進(jìn)入 CollageViewController 后退出后可以發(fā)現(xiàn)內(nèi)存不斷增長号枕,在內(nèi)存中搜索類名能看到這個視圖控制器沒有被釋放缰揪,還有一些其他相關(guān)的類。這樣就能知道是否有泄漏存在了堕澄。當(dāng)然了邀跃,這個代碼很容易查到原因,只需要點(diǎn)擊進(jìn)入每行對應(yīng)的代碼查看蛙紫,查看到 CollagePaperSizeView 時會指引到 paperSizeView 的 Block 中有循環(huán)引用。

Mark Generation

如果問題這么容易就定位到了途戒,Bishop 也就不用寫一大篇文章了坑傅,上面是剛好我們能搜到類名,正好出現(xiàn)問題的地方用了類名喷斋。如果搜索不出來應(yīng)當(dāng)怎么辦呢唁毒,那么 Mark Generation 該上場了。

就像 Bishop 所說的一樣星爪,按照重現(xiàn)步驟操作浆西,在出現(xiàn)問題的頁面進(jìn)入之前 Mark 一下,進(jìn)入頁面退出后再 Mark 一下顽腾。

這樣會生成 Generation A 和 Generation B近零,展開 Generation B ,看 Persistent 數(shù)最多的抄肖,這里是 non-object久信,再展開估計(jì)也看不出來什么了,點(diǎn)擊進(jìn)入 non-object漓摩,查看詳細(xì)裙士,接下來的頁面也是很多數(shù)據(jù),可以將 Responsible Libaray 列排序管毙,然后找到你的項(xiàng)目名字腿椎。

leak2.jpg

這里就沒有那么多噪聲了桌硫,很容易就能找到哪個是出問題的地方,看這里提示 save 方法有問題啃炸,就是該方法中出現(xiàn)了循環(huán)引用了鞍泉。

緩存

之后我想起來:這就是我們通常所謂的 Xcode,我打開終端肮帐,然后執(zhí)行 fuxcode (我寫的一個清理所有 DerivedData 的腳本)咖驮。又一次的重新編譯之后 Instruments 確認(rèn)沒有任何泄漏了。

Xcode 有緩存估計(jì)很多人都經(jīng)歷過這個痛楚吧训枢。寫個腳本把所有的 DerivedData 刪除 (哦托修,刪吧,刪了能把硬盤騰出很多地方)恒界,或者只刪除當(dāng)前項(xiàng)目的 DerivedData 吧睦刃,點(diǎn)擊菜單 Xcode -> Product,按住 Option 鍵十酣,Clean 變成 Clean Build Folder涩拙,清理下編譯目錄即可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末耸采,一起剝皮案震驚了整個濱河市兴泥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌虾宇,老刑警劉巖搓彻,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嘱朽,居然都是意外死亡旭贬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門搪泳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來稀轨,“玉大人,你說我怎么就攤上這事岸军》芄簦” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵凛膏,是天一觀的道長杨名。 經(jīng)常有香客問我,道長猖毫,這世上最難降的妖魔是什么台谍? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮吁断,結(jié)果婚禮上趁蕊,老公的妹妹穿的比我還像新娘坞生。我一直安慰自己,他們只是感情好掷伙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布是己。 她就那樣靜靜地躺著,像睡著了一般任柜。 火紅的嫁衣襯著肌膚如雪卒废。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天宙地,我揣著相機(jī)與錄音摔认,去河邊找鬼。 笑死宅粥,一個胖子當(dāng)著我的面吹牛参袱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播秽梅,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼抹蚀,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了企垦?” 一聲冷哼從身側(cè)響起环壤,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎竹观,沒想到半個月后镐捧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡臭增,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了竹习。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片誊抛。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖整陌,靈堂內(nèi)的尸體忽然破棺而出拗窃,到底是詐尸還是另有隱情,我是刑警寧澤泌辫,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布随夸,位于F島的核電站,受9級特大地震影響震放,放射性物質(zhì)發(fā)生泄漏宾毒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一殿遂、第九天 我趴在偏房一處隱蔽的房頂上張望诈铛。 院中可真熱鬧乙各,春花似錦、人聲如沸幢竹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽焕毫。三九已至蹲坷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間邑飒,已是汗流浹背循签。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留幸乒,地道東北人懦底。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像罕扎,于是被迫代替她去往敵國和親聚唐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容