iOS 中應(yīng)對內(nèi)存泄漏

instruments 檢查內(nèi)存泄漏

蘋果原生支持的工具,在開發(fā)模式下調(diào)試性能,但無法和自動化,CI進行結(jié)合。

  1. 在xcode中對當(dāng)前項目執(zhí)行Profile,打開leak模板
  2. 在leak中選擇對應(yīng)的設(shè)備和程序,點運行,如下圖
leak01.png

在導(dǎo)航欄中可以輸入關(guān)鍵字篩選數(shù)據(jù),在實際使用中,我們可以對一個頁面退出后,若該頁面中相關(guān)內(nèi)存分配還沒清空,這時候就發(fā)生內(nèi)存泄漏了。

AddressSanitizer

使用AddressSanitizer分析內(nèi)存泄漏。AddressSanitizer開啟之后,在debug過程中,如果遇到EXC_BAD_ACCESS的問題,Xcode會自動中斷,拋出異常。AddressSanitizer的原理是當(dāng)程序創(chuàng)建變量分配一段內(nèi)存時,將此內(nèi)存后面的一段內(nèi)存也凍結(jié)住,標識為中毒內(nèi)存。當(dāng)程序訪問到中毒內(nèi)存時(越界訪問),就會拋出異常,并打印出相應(yīng)log信息。調(diào)試者可以根據(jù)中斷位置和的log信息,識別bug。如果變量釋放了,變量所占的內(nèi)存也會標識為中毒內(nèi)存,這時候訪問這段內(nèi)存同樣會拋出異常(訪問已經(jīng)釋放的對象)。


實驗2.png

下面制造一個訪問野指針的場景,array被釋放后,繼續(xù)使用


訪問野指針.png

此時使用AddressSanitizer,可以看到使用野指針的地方拋出了異常。

addressSanitizer00.png

此時復(fù)制其地址,在XCode中Debug->Debug Workflow->View Memory,查看該內(nèi)存的使用情況,可以看到array已經(jīng)被釋放。

addressSanitizer.png

NSZombieEnabled

可以定位一些EXC_BAD_ACCESS問題,在對象被錯誤釋放的情況下,可以定位到具體的錯誤使用被已被釋放內(nèi)存的對象。zombie的原理是用生成僵尸對象來替換dealloc的實現(xiàn),當(dāng)對象引用計數(shù)為0的時候,將需要dealloc的對象轉(zhuǎn)化為僵尸對象。如果之后再給這個僵尸對象發(fā)消息,則拋出異常,并打印出相應(yīng)的信息
具體的設(shè)置,product->edit scheme->argument 下的Environment Variables。添加環(huán)境變量,NSZombieEnabled值為YES即可。在XCode8中在edit scheme中diagnositics中勾選Zombie Objects。如下圖

zombie勾選.png

同上制造訪問野指針的場景,看到下圖,可以看到有message發(fā)給已經(jīng)被dealloc的對象,導(dǎo)致異常。

zombie_結(jié)果.png

compiler flags

undefined-trap可以檢測出程序中的不明確行為,如數(shù)據(jù)溢出等。如下圖所示當(dāng)數(shù)據(jù)發(fā)生溢出時,系統(tǒng)會拋出異常。

數(shù)據(jù)溢出.png

All Exceptions

當(dāng)crash停在main中時,可能是EXC_CRASH(SIGABRT)或EXC_BAD_ACCESS(SIGBUG/SIGSEGV)導(dǎo)致的??梢栽谌旨訑帱c的方式來查看是哪一行導(dǎo)致了crash。
下面制造一個crash,如下圖:

crash01.png

此時運行,會報錯,如下圖:


crash01_result01.png

此時選擇All Exception,就可以看到具體哪行crash了

all_exception.png
crash_01_result02.png

靜態(tài)檢查

在product中選擇Analyze??梢詸z查出明顯沒有釋放的內(nèi)存,主要在兩種場景中使用,
MRC文件中忘記release或者autorelease,C方式申請內(nèi)存中忘記釋放內(nèi)存,遺漏了free。
在關(guān)閉ARC的情況下,打開product->Analyze,可以看到下圖,圖中藍色標記的為有問題的地方。

analyze.png

method_exchangeImplementations

使用method_exchangeImplementations接管alloc和dealloc,記錄每一次內(nèi)存分配和地址,再遍歷堆區(qū),全局區(qū),棧區(qū)的指針變量,進行比較,找出沒有指針變量指向的內(nèi)存地址。(這個好像比較高階,還沒實驗成功)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容