Objective-C內(nèi)存管理 調(diào)試內(nèi)存泄露
Objective-C內(nèi)存管理 調(diào)試內(nèi)存泄露是本文要介紹的內(nèi)容,解決內(nèi)容問題應(yīng)該每個迭代周期要做一些壓力和內(nèi)存測試,我們先來看內(nèi)容。
1、內(nèi)存的問題是發(fā)現(xiàn)越早,解決的代價就越小。所以最重要的是理解Objective-C內(nèi)存管理,遵循我之前提到的實踐準則和編碼規(guī)范。另外,在每個迭代周期要做一些壓力和內(nèi)存測試,盡早發(fā)現(xiàn)問題。
2、利用Clang靜態(tài)檢測工具。在XCode 3.2之后的版本里,Clang已經(jīng)被集成進來。Build ->Build & Analyze即可運行,它可以發(fā)現(xiàn)大部分因為疏忽造成的內(nèi)存泄露。比如有Alloc沒有release等。下圖是一次靜態(tài)檢測的結(jié)果. 如圖所示,Clang清楚的告訴你在145行有潛在的內(nèi)存泄露,即label有alloc沒有release。(單擊放大)
圖一 Clang靜態(tài)檢測
3、如果靜態(tài)檢測工具不能解決問題,就需要更多的分析和借助instruments工具。
(1)首先要重現(xiàn)問題,找到是哪些操作容易產(chǎn)生內(nèi)存泄露。主要通過一些測試和推理來判斷,比如找出哪些操作重復(fù)進行時,內(nèi)存增長比較明顯或者會Crash。
b)借助instruments工具。instruments是在程序運行時在程序中注入一些代碼來動態(tài)的檢測內(nèi)存分配狀況和泄露問題。Run -> Run with perfomance tools - > leaks 即可啟動。下圖是運行l(wèi)eak instrument的一次結(jié)果,如果leak是你的代碼引起的,你還可以直接查看到引起泄露的代碼。(單擊放大)
圖二 leaked Blocks
圖三 leaked code(單擊放大)
(2)還有一個instrument叫Allocation,它可以實時監(jiān)測當(dāng)前分配了多少內(nèi)存。結(jié)合這個來進行a)步驟的推斷,往往會比較有效。可以通過Run -> Run with perfomance tools - >Allocations啟動,也可以在instruments啟動后通過window->library ->Allocations加進來。
4、可以找你的同事codereview,旁觀者往往能發(fā)現(xiàn)問題。有時候內(nèi)存泄露是一些理解上的誤區(qū)造成的。比如我以前一直以為 -viewDidUnload是在這個View被unload之后調(diào)用,所以我在里面做一些清理工作,比如Remove EventHandler等, 后來才知道這個函數(shù)是在內(nèi)存不足需要unload view時才被調(diào)用,這個理解誤區(qū)導(dǎo)致我花了一周的時間解決一個內(nèi)存泄露的bug。 還有一個例子,之前我的一個同事一直以為[NSDate new]是產(chǎn)生當(dāng)前時間,并不需要釋放,這也是一個比較低級的理解誤區(qū)。
5、有些內(nèi)存問題可能是緩存引起的,并不一定是泄露。比如在Three20(Facebook IPhone Library)里,出于性能的考慮,默認會在內(nèi)存里cache一些網(wǎng)絡(luò)圖片. [UIImage imageNamed:]也會把圖片放到system cache里面,這不能算是泄露,但有時候會引起內(nèi)存不足。
小結(jié):Objective-C內(nèi)存管理 調(diào)試內(nèi)存泄露的內(nèi)容介紹完了,希望本文對你有所幫助。