iOS_ 性能優(yōu)化_內(nèi)存優(yōu)化_Leaks工具的使用

<h3>內(nèi)存優(yōu)化:</h3>
Objective_C 有3種內(nèi)存管理方法, 它們分別是 <b>MRR (Manual Retain Release, 手動保持釋放), ARC(Automatic Reference Counting, 自動引用計數(shù)) 和 GC(Garbage Collection, 垃圾收集)</b>, 下面我們分別介紹一下它們.

1><b>MRR</b> 也稱為 MRC(Manual Reference Counting, 手動引用計數(shù)), 就是由程序員自己負(fù)責(zé)管理對象生命周期,負(fù)責(zé)對象的創(chuàng)建和銷毀.

2><b>ARC</b>.采用和 MRR 一樣的內(nèi)存引用計數(shù)管理方法, 但不同的是, 它在編譯時會在何時的位置插入對象內(nèi)存釋放, (如 release, autorelease, 和 retain 等), 程序員不用關(guān)心對象釋放的問題, 蘋果推薦在新項目中使用 ARC, 但在 iOS5之前的系統(tǒng)中不能采用 ARC.

3><b>GC</b>. 在Objective_C2.0之后, 內(nèi)存管理出現(xiàn)了類似于 Java 和 C#的內(nèi)存垃圾收集技術(shù), 但是垃圾收集與 ARC 一直運(yùn)行, 垃圾收集是后臺有一個線程負(fù)責(zé)檢查已經(jīng)不再使用的對象,然后釋放之. 由于后臺有一個線程一直運(yùn)行, 一次會嚴(yán)重影響性能, 這也是 Java 和 C#程序的運(yùn)行速度無法超越 C++的主要原因. GC 技術(shù)不能應(yīng)用于 iOS 開發(fā), 只能應(yīng)用于Mac OS X 開發(fā).

從上面的介紹可知, iOS 采用 MRR 和 ARC 這兩種方式, ARC 是蘋果推薦的方式, MRR 方式相對比較原始, 對于程序員的能力要求很高, 但是它很靈活, 方便, 很不容易駕馭好.

<h4>內(nèi)存泄露問題的解決</h4>
<h5>1>Analyze + Leaks 的使用</h5>
內(nèi)存泄露指當(dāng)一個對象或變量在使用完成后沒有釋放掉, 這個對象一直占用著這部分內(nèi)存, 直到應(yīng)用停止. 如果這種對象過多,內(nèi)存就會耗盡,其他應(yīng)用就無法運(yùn)行.這個問題在 C++, C 和 Objective-C的 MRR 中是比較普遍的問題.

從理論上講, 內(nèi)存泄露是由對象或變量沒有釋放引起的, 但實踐證明并非所有的未釋放的對象或變量都會導(dǎo)致內(nèi)存泄露, 這與硬件環(huán)境和操作系統(tǒng)系統(tǒng)環(huán)境有關(guān), 因此我們需要檢測工具幫助我們找到這些"泄漏點".

在 Xcode 中, 共提供了兩種工具幫助查找泄漏點,
<b> Analyze 和 Instruments. </b>
<b>Analyze 是靜態(tài)分析工具.</b> 可以通過 Product ->Analyze 菜單項啟動. 快捷鍵: CMD+shift +b.
<b>Instruments:是動態(tài)分析工具</b>, 它與 Xcode 集成在一起,可以在 Xcode 中通過 Product ->Profile 菜單項啟動. 快捷鍵 CMD + i.它有很多跟蹤模塊可以動態(tài)分析和跟蹤內(nèi)存, CPU 和文件系統(tǒng).

Instruments動態(tài)分析工具

我們可以結(jié)合使用這兩個工具查找泄漏點. 先使用 Analyze 靜態(tài)分析查找可疑泄漏點, 再用Instruments動態(tài)分析中的 Leaks 和 Allocations 跟蹤模板進(jìn)行動態(tài)跟蹤分析, 確認(rèn)這些點是否泄漏, 或者是否有新的泄漏點出現(xiàn)等.
1>在 Analyze 靜態(tài)分析結(jié)果中, 凡是有圖標(biāo)


分析結(jié)果圖標(biāo)

出現(xiàn)的行都是工具發(fā)現(xiàn)的疑似泄漏點.

疑似泄漏點所在行

點擊疑似泄漏點行末尾的分叉圖標(biāo),會展開分析結(jié)果.
這里使用 Analyze 靜態(tài)分析查找出來的泄漏點,稱之為"可疑泄漏點".之所以稱之為"可疑泄漏點",是因為這些點未必一定泄露,確認(rèn)這些點是否泄露, 還要通過 Instruments 動態(tài)分析工具的 Leaks 和 Allocations 跟蹤模板. Analyze 靜態(tài)分析只是一個理論上的預(yù)測過程.
在 Xcode 中通過 Product ->Profile 菜單項啟動 Instruments 動態(tài)分析工具, 接著選擇 Leaks 模板, 打開界面如下:

Leaks

在 instruments 中,雖然選擇了 Leaks 模板,但默認(rèn)情況下也會添加 Allocations 模板.基本上凡是內(nèi)存分析都會使用 Allocations 模板, 它可以監(jiān)控內(nèi)存分布情況, 選中 Allocations 模板,(圖1區(qū)域),右邊的3區(qū)域會顯示隨著時間的變化內(nèi)存使用的折線圖,同時在4區(qū)域會顯示內(nèi)存使用的詳細(xì)信息,以及對象分配情況. 點擊 Leaks 模板(圖中2區(qū)域), 可以查看內(nèi)存泄露情況颇象。如果在3區(qū)域有 紅X 出現(xiàn), 則有內(nèi)存泄露, 4區(qū)域則會顯示泄露的對象.

點擊泄露對象可以在(下圖)看到它們的內(nèi)存地址, 占用字節(jié), 所屬框架和響應(yīng)方法等信息.
打開擴(kuò)展視圖, 可以看到右邊的跟蹤堆棧信息, 其中
![Uploading Paste_Image_349106.png . . .]
圖標(biāo)所示的條目是我們自己的應(yīng)用的代碼,點擊它即可進(jìn)入程序代碼.


Paste_Image.png

<h4>具體使用</h4>
1.Allocations紀(jì)錄了內(nèi)存分配恭应,用來優(yōu)化內(nèi)存使用的
2.Leaks用來分析內(nèi)存泄漏敛纲。ARC中引起的內(nèi)存泄漏原因就是引用環(huán)。

<b>第一步</b>先選擇Leaks和Leaks by Backtrace.這里可以看到那些對象內(nèi)存泄漏了像云,泄漏了多少掺出,這個就是簡單看看,沒有太多調(diào)試意義苫费。

Leaks by Backtrace.

<b>第二步</b>然后看看Call Tree,因為Call Tree會給我們大概的位置双抽,有時候會給我們精確的位置百框,不過要看運(yùn)氣了。
然后牍汹,再右面選擇Invert Call Tree和Hide System Library


Call Tree

然后雙擊 上文圖片中的任意一行铐维,就會跳到代碼處內(nèi)存泄漏的地方(事實上,到這步慎菲,很多內(nèi)存泄漏的問題都會被發(fā)現(xiàn)),當(dāng)然也有一些泄露還是看不出來的.

<b>第三步</b>然后我們選擇對ARC調(diào)試很有用的一個部分Circles & Roots嫁蛇,通過這個我們可以看到詳細(xì)的ARC引用計數(shù)過程。
然后露该,我們看到如下圖

小的紅色矩形點擊可以看到引用計數(shù)的詳細(xì)信息(ARC 就是自動引用計數(shù)睬棚,計數(shù)為0,則對象會被釋放)
大的紅色矩形可以繪制對象引用環(huán)的圖解幼,這里如果是我們自己的東西,就能看出來各個對象之間的引用.

Circles & Roots

如果這里沒有引用環(huán)的圖. 首先我們找一下我們自定義的對象,正常完成任務(wù)這個對就應(yīng)該釋放的. 為了確認(rèn)這個對象有沒有釋放, 可以重寫 dealloc 方法, 在此方法中 log 釋放信號, 看看是否被釋放.
如果這里就是沒有釋放,我們可以點擊這兒對象后的箭頭詳細(xì)的看下, 這個對象的引用計數(shù)變化如圖.

All 表示所有的引用計數(shù)變化
Unpaired表示那些為成對的變化``(成對就是leaks識別出了對應(yīng)的+1抑党,-1)
By Group會把相關(guān)的變化分成一組,
ByTime會按照順序列出引用計數(shù)變化

Paste_Image.png

我們選擇Unpaired 和 ByGroup撵摆,看到如圖

Paste_Image.png

按照順序看(最左邊的標(biāo)號)
4 這里底靠,引用計數(shù)是一,這是正確的特铝,因為到這里正常就是應(yīng)該是OperationQueue保存一個Operation的引用暑中。 于是壹瘟,我們把正常的劃掉

Paste_Image.png

再繼續(xù)看,download start 標(biāo)號6和8是對應(yīng)的鳄逾,繼續(xù)排除問題出現(xiàn)在這里(當(dāng)然問題不可能出現(xiàn)在這里稻轨,這是系統(tǒng)的API,一定會釋放严衬,就是簡單教大家如何看)

Paste_Image.png

再看看澄者,+1的還剩下標(biāo)號7 和 11,7 是正常的為Operation分配線程请琳,應(yīng)當(dāng)會+1粱挡,而11就是我們的問題所在了(大部分Delegate都不會使引用+1)。 我們再看下文檔

@property(readonly, retain) id< NSURLSessionDelegate > delegate

原來這個代理是retain啊俄精,不是assign或者weak询筏。所以形成了這樣的引用環(huán)。

Paste_Image.png

那么怎么辦呢竖慧?有問題下看文檔嫌套,我們看到圖片中引起引用計數(shù)加一的是

+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(id<NSURLSessionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue:

看下文檔,發(fā)現(xiàn)了這個地方

Paste_Image.png

于是圾旨,我們要手動的去斷開強(qiáng)引用踱讨,于是,我們手動去斷開

-(void)setOperationFinished
{ 
[self.session invalidateAndCancel];
}

再運(yùn)行下看看砍的,能夠正常的Dealloc了.

總結(jié):其實大多數(shù)問題在雙擊上文的代碼部分就可以解決了痹筛,少數(shù)問題需要詳細(xì)的分析ARC引用過程。

<b>寫到最后</b>

如果我們未發(fā)現(xiàn)表示內(nèi)存泄露的紅 X, 但是我們想進(jìn)一步評估某個對象對于內(nèi)存的應(yīng)用, 可以看看 Allocations 模板的折線圖. 反復(fù)執(zhí)行從創(chuàng)建對象 -> 銷毀對象 這個過程, 如果總占用內(nèi)存數(shù)會隨之增加, 這說明這個對象沒有釋放, 有些時候雖然占用的內(nèi)存不是很嚴(yán)重, 但是也會增加占用內(nèi)存, 因此必須釋放這個對象.

提示:有些情況下, 對象沒有釋放是無法檢測到的,反復(fù)測試內(nèi)存占用也沒有明顯的增加, 這時最好在配置比較低的設(shè)備上測試一下, 如果問題依然, 可以不用釋放對象. 但是從編程習(xí)慣上講, 我們應(yīng)該釋放該對象.

事實上,內(nèi)存泄露是及其復(fù)雜的問題, 工具使用是一方面, 經(jīng)驗是另一方面. 提高經(jīng)驗, 然后借助工具才能解決內(nèi)存泄露的根本.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末廓鞠,一起剝皮案震驚了整個濱河市帚稠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌床佳,老刑警劉巖滋早,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異砌们,居然都是意外死亡杆麸,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門怨绣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來角溃,“玉大人,你說我怎么就攤上這事篮撑〖跸福” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵赢笨,是天一觀的道長未蝌。 經(jīng)常有香客問我驮吱,道長,這世上最難降的妖魔是什么萧吠? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任左冬,我火速辦了婚禮,結(jié)果婚禮上纸型,老公的妹妹穿的比我還像新娘拇砰。我一直安慰自己,他們只是感情好狰腌,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布除破。 她就那樣靜靜地躺著,像睡著了一般琼腔。 火紅的嫁衣襯著肌膚如雪瑰枫。 梳的紋絲不亂的頭發(fā)上援雇,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天咪笑,我揣著相機(jī)與錄音旺矾,去河邊找鬼矫废。 笑死,一個胖子當(dāng)著我的面吹牛拉盾,可吹牛的內(nèi)容都是我干的蛙吏。 我是一名探鬼主播兄一,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼洲赵,長吁一口氣:“原來是場噩夢啊……” “哼土铺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起板鬓,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎究恤,沒想到半個月后俭令,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡部宿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年抄腔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片理张。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡赫蛇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雾叭,到底是詐尸還是另有隱情悟耘,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布织狐,位于F島的核電站暂幼,受9級特大地震影響筏勒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜旺嬉,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一管行、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧邪媳,春花似錦捐顷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至设易,卻和暖如春逗柴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背顿肺。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工戏溺, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人屠尊。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓旷祸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親讼昆。 傳聞我的和親對象是個殘疾皇子托享,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348

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