iOS開(kāi)發(fā)中,難免會(huì)出現(xiàn)內(nèi)存泄漏的情況,此處通過(guò)instruments 中的 leaks工具來(lái)檢測(cè)程序的內(nèi)存泄漏問(wèn)題;
instruments的介紹:
instruments是一個(gè)很靈活、強(qiáng)大的工具,是性能分析、動(dòng)態(tài)跟蹤 和 分析OSX以及iOS代碼的測(cè)試工具;用他可以極為方便的收集關(guān)于一個(gè)或多個(gè)系統(tǒng)進(jìn)程的性能和行為的數(shù)據(jù),并能及時(shí)隨著時(shí)間跟蹤而產(chǎn)生數(shù)據(jù),并檢查所收集的數(shù)據(jù),還可以廣泛收集不同類型的數(shù)據(jù);也可以追蹤程序運(yùn)行的過(guò)程,這樣instruments就可以幫助我們了解用戶的應(yīng)用程序和操作系統(tǒng)的行為。
使用instruments的leaks工具
迅速膨脹的內(nèi)存可以很快讓程序斃命,所以要多加防范,即使有ARC(自動(dòng)引用計(jì)數(shù))內(nèi)存管理機(jī)制,但是在現(xiàn)實(shí)中對(duì)象之間的引用復(fù)雜,循環(huán)引用 ,以及C層次的代碼都有可能導(dǎo)致內(nèi)存泄漏,所以需要用到 leaks。
打開(kāi)的界面如圖(新版本)

由于Leaks是動(dòng)態(tài)監(jiān)測(cè),所以我們需要手動(dòng)操作APP,進(jìn)行測(cè)試,一邊操作APP,一邊觀察Leaks的變化,在 ? 暫停按鈕 ?的右側(cè)可以選擇 運(yùn)行的設(shè)備 和 運(yùn)行的項(xiàng)目 (需要首先將項(xiàng)目安裝到設(shè)備上),點(diǎn)擊開(kāi)始按鈕運(yùn)行, 操作APP 當(dāng)發(fā)現(xiàn)leaks 中 有一個(gè)紅色的X,這說(shuō)明APP存在內(nèi)存泄漏,然后點(diǎn)擊暫停,點(diǎn)擊其中一個(gè),然后開(kāi)始分析(也可繼續(xù)檢測(cè),當(dāng)多個(gè)時(shí)暫停,一次處理了多個(gè))。
下面就是定位修改了
1、選中有紅色X的Leaks,下面有個(gè)?田?Leaks 字方格,點(diǎn)開(kāi),選中 Call Tree。

2、接著就是最關(guān)鍵的一步,在這個(gè)界面的右下角有若干選框,選中Invert Call Tree 和 Hide System Libraries,(紅圈范圍內(nèi))如果不知道在那個(gè)位置請(qǐng)接著往下看 (如果call tree 沒(méi)有刷新,可以勾掉重新勾選)

3、定位 (APP 中 應(yīng)該設(shè)定 Build Settings -> Debug Information Format 的Debug改成DWARF with dSYM File,這樣才能看到具體位置)
在詳情面板選中顯示的若干條中的一條,雙擊,會(huì)自動(dòng)跳到內(nèi)存泄露代碼處,然后點(diǎn)擊右上角 Xcode 圖標(biāo)進(jìn)行修改。
4、舉例


5、這里對(duì) Display Settings 中 的Call tree選項(xiàng)做一下說(shuō)明 [官方user guide翻譯]:
Separate By Thread: 線程分離,只有這樣才能在調(diào)用路徑中能夠清晰看到占用CPU最大的線程.每個(gè)線程應(yīng)該分開(kāi)考慮。只有這樣你才能揪出那些大量占用CPU的"重"線程,按線程分開(kāi)做分析,這樣更容易揪出那些吃資源的問(wèn)題線程。特別是對(duì)于主線程,它要處理和渲染所有的接口數(shù)據(jù),一旦受到阻塞,程序必然卡頓或停止響應(yīng)。
Invert Call Tree: 從上到下跟蹤堆棧信息.這個(gè)選項(xiàng)可以快捷的看到方法調(diào)用路徑最深方法占用CPU耗時(shí)(這意味著你看到的表中的方法,將已從第0幀開(kāi)始取樣,這通常你是想要的,只有這樣你才能看到CPU中話費(fèi)時(shí)間最深的方法),比如FuncA{FunB{FunC}},勾選后堆棧以C->B->A把調(diào)用層級(jí)最深的C顯示最外面.反向輸出調(diào)用樹(shù)。把調(diào)用層級(jí)最深的方法顯示在最上面,更容易找到最耗時(shí)的操作。
Hide System Libraries: 表示隱藏系統(tǒng)的函數(shù),調(diào)用這個(gè)就更有用了,勾選后耗時(shí)調(diào)用路徑只會(huì)顯示app耗時(shí)的代碼,性能分析普遍我們都比較關(guān)系自己代碼的耗時(shí)而不是系統(tǒng)的.基本是必選項(xiàng).注意有些代碼耗時(shí)也會(huì)納入系統(tǒng)層級(jí),可以進(jìn)行勾選前后前后對(duì)執(zhí)行路徑進(jìn)行比對(duì)會(huì)非常有用.因?yàn)橥ǔD阒魂P(guān)心cpu花在自己代碼上的時(shí)間不是系統(tǒng)上的,隱藏系統(tǒng)庫(kù)文件。過(guò)濾掉各種系統(tǒng)調(diào)用,只顯示自己的代碼調(diào)用。隱藏缺失符號(hào)。如果 dSYM 文件或其他系統(tǒng)架構(gòu)缺失,列表中會(huì)出現(xiàn)很多奇怪的十六進(jìn)制的數(shù)值,用此選項(xiàng)把這些干擾元素屏蔽掉,讓列表回歸清爽。
Flatten Recursion: 遞歸函數(shù), 每個(gè)堆棧跟蹤一個(gè)條目,拼合遞歸。將同一遞歸函數(shù)產(chǎn)生的多條堆棧(因?yàn)檫f歸函數(shù)會(huì)調(diào)用自己)合并為一條。