??內(nèi)存泄漏,通俗來說就是有一塊內(nèi)存區(qū)域被你占用了,但你又不使用這塊區(qū)域也不讓別人用,造成內(nèi)存浪費,這就是內(nèi)存泄漏,泄漏嚴重會造成內(nèi)存吃緊,嚴重的會使程序崩潰。
在ARC內(nèi)存管理模式下,產(chǎn)生內(nèi)存泄露的的情況如下:
- retain cycle,block強引用
- delegate循環(huán)引用問題
- 定時器NSTimer釋放不當
- 第三方提供方法造成的內(nèi)存泄漏
- CoreFoundation方式申請的內(nèi)存,忘記釋放
一、使用Instruments的Leaks工具進行內(nèi)存泄露的檢測
demo在最下面給出
打開Xcode自帶的Instruments
方法一:

方法二:
或者:下圖
build成功后自動跳出Instruments工具,選擇Leaks選項即可
方法三:
或者:長按運行按鈕,然后出現(xiàn)如圖所示列表,點擊
Profile
在下面的
Instruments列表中選擇Leaks
以上算是打開Instruments的基本方法,下面開始進行使用Instruments進行內(nèi)存泄漏檢測
-
首先編譯代碼,上面的方法二,快捷鍵(
command+i),編譯完成彈出Instruments選擇Leaks
Leaks -
點擊上面開始運行項目,這時候會啟動app
啟動app -
對于啟動的項目,點擊按鈕push到第二個界面,再次pop回來,反復(fù)幾次,為了內(nèi)存泄漏更明顯一點
app界面1
app界面2 -
接下來會發(fā)現(xiàn)出現(xiàn)紅色的x,這個就表示出現(xiàn)了內(nèi)存泄漏
Leaks -
在下面的模式中切換到
Call Tree模式下,可以看到列表里列出了內(nèi)存泄露的調(diào)用邏輯:
Call Tree -
下面就是
最關(guān)鍵的一步,在這個界面的下面有若干選框,在Call Tree選項中選中Separate by Thread和Hide system Libraries
Leaks選項
Separate By Thread:線程分離,只有這樣才能在調(diào)用路徑中能夠清晰看到占用CPU最大的線程。每個線程應(yīng)該分開考慮。只有這樣你才能揪出那些大量占用CPU的"重"線程,按線程分開做分析,這樣更容易揪出那些吃資源的問題線程。特別是對于主線程,它要處理和渲染所有的接口數(shù)據(jù),一旦受到阻塞,程序必然卡頓或停止響應(yīng)。
Invert Call Tree:從上到下跟蹤堆棧信息.這個選項可以快捷的看到方法調(diào)用路徑最深方法占用CPU耗時(這意味著你看到的表中的方法,將已從第0幀開始取樣,這通常你是想要的,只有這樣你才能看到CPU中話費時間最深的方法),比如FuncA{FunB{FunC}},勾選后堆棧以C->B->A把調(diào)用層級最深的C顯示最外面.反向輸出調(diào)用樹。把調(diào)用層級最深的方法顯示在最上面,更容易找到最耗時的操作。
Hide System Libraries:表示隱藏系統(tǒng)的函數(shù),調(diào)用這個就更有用了,勾選后耗時調(diào)用路徑只會顯示app耗時的代碼,性能分析普遍我們都比較關(guān)系自己代碼的耗時而不是系統(tǒng)的?;臼潜剡x項。注意有些代碼耗時也會納入系統(tǒng)層級,可以進行勾選前后前后對執(zhí)行路徑進行比對會非常有用.因為通常你只關(guān)心cpu花在自己代碼上的時間不是系統(tǒng)上的,隱藏系統(tǒng)庫文件。過濾掉各種系統(tǒng)調(diào)用,只顯示自己的代碼調(diào)用。隱藏缺失符號。如果 dSYM 文件或其他系統(tǒng)架構(gòu)缺失,列表中會出現(xiàn)很多奇怪的十六進制的數(shù)值,用此選項把這些干擾元素屏蔽掉,讓列表回歸清爽。
Flatten Recursion:遞歸函數(shù), 每個堆棧跟蹤一個條目,拼合遞歸。將同一遞歸函數(shù)產(chǎn)生的多條堆棧(因為遞歸函數(shù)會調(diào)用自己)合并為一條。
-
選中顯示的若干條中的一條,雙擊,會自動跳到內(nèi)存泄露代碼處,如圖所示:
泄漏提示
雙擊后顯示如下:
問題代碼 接下來就可以修改問題代碼來解決內(nèi)存泄漏問題
注意
在選擇
Call Tree后,可能你會發(fā)現(xiàn)查看不到源碼從而無法定位內(nèi)存泄漏的位置,只是顯示16進制的數(shù)據(jù)。此時需要你在Xcode中檢查是否有dSYM File生成,如下圖所示選擇第二項DWARF with dSYM File。
注意點









