iOS APP內(nèi)存泄漏: MLeaksFinder與 Debug Memory Graph簡(jiǎn)介

更新

升級(jí)到 Xcode8之后, 這個(gè)庫好像沒有用了, 具體原因也不詳細(xì)追究了, 因?yàn)?Xcode 自帶了強(qiáng)大的 Debug Memory Graph, 直接以關(guān)系圖的形式來告訴你各個(gè)對(duì)象的持有關(guān)系, 以及出現(xiàn)了泄露時(shí)會(huì)有紫色的小感嘆號(hào)出現(xiàn), 不出現(xiàn)也不意味著沒有喲, 所以還需要用這個(gè)工具時(shí)不時(shí)看看現(xiàn)有的存活對(duì)象中有沒有期望之外的.
下面是一些關(guān)鍵步驟的截圖:


Debug Memory Graph入口
出現(xiàn)紫色警告意味著泄露了, 但是貌似不太準(zhǔn)確
警告導(dǎo)航欄列出了所有的泄露點(diǎn)

如果在警告列表中沒有看到任何東西, 先切換到 BuildTime 那里把右下角的警告篩選給關(guān)了就會(huì)出現(xiàn)了, 個(gè)人認(rèn)為這是 Xcode 的一個(gè) bug...

這里列出了先階段所有的"存活"對(duì)象

選中某個(gè)泄露對(duì)象后會(huì)出現(xiàn)持有和它有關(guān)系的對(duì)象關(guān)系圖, 如下:

引用關(guān)系圖

這個(gè)例子說我們的 ViewController 被 block 持有了, 點(diǎn)擊紅圈里面的展開可以看到更多的信息, 具體過程就不詳細(xì)講了, 因?yàn)檫@里給到的信息已經(jīng)足夠詳細(xì), 再需要一些耐心就可以找出具體的原因了.

!注意: 不要開著 NSZombie 來檢測(cè), 不然你會(huì)發(fā)現(xiàn)一大票的泄露.

新工具簡(jiǎn)介就到這邊了, 下面的老的MLeaksFinder的內(nèi)容, 已經(jīng)過時(shí), 不讀也罷...

前言

一般來說, iOS的內(nèi)存泄露檢測(cè)大多是通過Instruments里面的Leaks. Leaks里面可以看到某各類有多少個(gè)實(shí)例, 還會(huì)指出一些循環(huán)引用的圖示和泄露點(diǎn). 雖然看起來很美好, 但是每次實(shí)際使用的時(shí)候, 多多少少會(huì)出現(xiàn)一些問題, 最讓人難以忍受的就是明明泄露了但是沒有報(bào)警.

為了解決這個(gè)問題, 在這里介紹一個(gè)MLeaksFinder的開源庫, 這個(gè)庫是代碼級(jí)別的檢測(cè)view和viewController是否出現(xiàn)內(nèi)存泄露的情況. 它的優(yōu)勢(shì)是只要引入后不侵入現(xiàn)有代碼, 正常跑一遍APP, 如果出現(xiàn)泄露, 將會(huì)觸發(fā)斷言打印相關(guān)日志提醒我們出現(xiàn)了泄露. 缺點(diǎn)也比較明顯了, 就是只能檢測(cè)view和viewController級(jí)別的泄露. 不過一般來說也足夠用了, 畢竟這是大頭.

github地址:https://github.com/Zepo/MLeaksFinde

原理

MLeaksFinder的原理還是很簡(jiǎn)單的, 它swizzle了NavigationController的Push和Pop相關(guān)方法來管理viewController和view的生命周期, 在你Pop掉viewController的時(shí)候, 會(huì)執(zhí)行這么一段代碼

__weak id weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [weakSelf assertNotDealloc];
    });

3秒后執(zhí)行 [weakSelf assertNotDealloc]; 如果這個(gè)時(shí)候view和viewController已經(jīng)釋放了, 那么weakSelf應(yīng)該為nil, 所以將不會(huì)觸發(fā)斷言, 否則將會(huì)打印日志, 觸發(fā)斷言.

實(shí)際操作

為了驗(yàn)證是否真正出現(xiàn)泄漏的情況, 可以在出現(xiàn)斷言的時(shí)候, 進(jìn)入Instruments的Leaks來看查看類實(shí)例個(gè)數(shù), 反復(fù)進(jìn)入目標(biāo)頁面后可以查看目標(biāo)類的實(shí)例情況,例如:



Persistent是當(dāng)前的實(shí)例個(gè)數(shù), 如果發(fā)現(xiàn)Pop之后沒有減少, 就肯定是泄漏了. 這里也吐槽一下Instrument, 這種情況是檢測(cè)不出來的.

發(fā)現(xiàn)泄漏點(diǎn)是第一步, 后面還要看怎么泄漏, 方法還是有很多的, 可以自己查相關(guān)頁面的代碼, 我的操作步驟一般是:

1). 點(diǎn)擊選中一行之后, Category列會(huì)出現(xiàn)箭頭, 如:
,

2). 進(jìn)入到實(shí)例頁面之后, 再選中實(shí)例再點(diǎn)擊箭頭會(huì)出現(xiàn)retain和release的時(shí)序列表. 這個(gè)時(shí)候很卡的話建議暫停運(yùn)行APP
3). 在這個(gè)時(shí)序表中查看有沒有不該retain但是retain了的函數(shù), 一般只需要看那些單獨(dú)+1 -1的行, 說明這里的retain和release是沒有平衡起來的, 除非是系統(tǒng)代碼或者有意為之, 否則都會(huì)有一些問題.
4). 發(fā)現(xiàn)可疑點(diǎn)之后, 雙擊進(jìn)入相關(guān)代碼, 查看泄露情況, 一般是選擇泄露比重最大的那一行代碼, 然后進(jìn)行深入分析.
5). 如果你也曾經(jīng)出現(xiàn)死活都找不到泄露的位置, 那么時(shí)候祭出大殺器--注釋代碼了.

另外, 對(duì)于一些view的泄露, 還是要善用一下Xcode自帶的功能, 一般我的操作會(huì)是跳到UIImageView或者UILabel的泄漏點(diǎn)選中self, 然后在變量區(qū)下面點(diǎn)擊那個(gè)眼睛, 如下圖:



看到里面的內(nèi)容就能大致猜出出現(xiàn)泄漏的地方了, 一般而言, view單獨(dú)泄漏的情況還是比較少的, 雖然也出現(xiàn)過, 但是總體而言都是viewController的泄漏連帶了view的泄漏.

結(jié)語

這個(gè)簡(jiǎn)單的庫幫助我找到了很多Instruments沒有報(bào)警的泄漏點(diǎn), 個(gè)人覺得很好用, 而且引入進(jìn)來就算忘記移出也沒關(guān)系, 已經(jīng)用DEBUG宏包裹起來了, 不會(huì)影響到發(fā)布.
另外, 有沒有同學(xué)遇到過前端頁面用了-webkit-overflow-scrolling:touch導(dǎo)致出現(xiàn)UIWebOverflowScrollView泄露的啊? 求指導(dǎo)解決.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌胁艰,老刑警劉巖底洗,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腋么,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡亥揖,警方通過查閱死者的電腦和手機(jī)珊擂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來费变,“玉大人摧扇,你說我怎么就攤上這事≈科纾” “怎么了扛稽?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長滑负。 經(jīng)常有香客問我在张,道長,這世上最難降的妖魔是什么橙困? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任瞧掺,我火速辦了婚禮耕餐,結(jié)果婚禮上凡傅,老公的妹妹穿的比我還像新娘。我一直安慰自己肠缔,他們只是感情好夏跷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著明未,像睡著了一般槽华。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上趟妥,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天猫态,我揣著相機(jī)與錄音,去河邊找鬼披摄。 笑死亲雪,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的疚膊。 我是一名探鬼主播义辕,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼寓盗!你這毒婦竟也來了灌砖?” 一聲冷哼從身側(cè)響起璧函,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎基显,沒想到半個(gè)月后蘸吓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡续镇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年美澳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摸航。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡制跟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酱虎,到底是詐尸還是另有隱情雨膨,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布读串,位于F島的核電站聊记,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏恢暖。R本人自食惡果不足惜排监,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杰捂。 院中可真熱鬧舆床,春花似錦、人聲如沸嫁佳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒿往。三九已至盛垦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瓤漏,已是汗流浹背腾夯。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔬充,地道東北人蝶俱。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像娃惯,于是被迫代替她去往敵國和親跷乐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

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