IOS效能調優系列:使用Zombies動態分析記憶體中的殭屍對象,調優zombies
硬廣:《IOS效能調優系列》第四篇,預計會有二十多篇,持續更新,歡迎關注。
前兩篇《IOS效能調優系列:Analyze靜態分析》、《IOS效能調優系列:使用Instruments動態分析記憶體流失》關注了記憶體泄露的問題,本篇正好相反,關注的是記憶體中那些被過度釋放的對象(overreleased objects)。
這篇的標題糾結了半天,到底是寫EXC_BAD_ACCESS錯誤調試,還是寫記憶體中殭屍對象的分析,最後還是選了個Duang~Duang~的標題。
今天在論壇上看到個文章,遇到的就是本篇要分析的問題,正好拿來解釋Bug情境:
相信在使用ARC之前,很多人遇到過EXC_BAD_ACCESS錯誤,這個錯誤可以理解為訪問了已被釋放的對象,蘋果稱之為殭屍對象。
比如在不開啟ARC下,下面這段代碼:
NSString* hello = [NSString stringWithFormat:@"Hello"]; NSLog(@"What you say is %@",hello); [hello release];
hello對象不是手動分配,而是加入到自動釋放池,由釋放池負責釋放,所以第三行調用release時就會產生EXC_BAD_ACCESS錯誤。
在開啟ARC後,可以很大程度上避免產生EXC_BAD_ACCESS錯誤,但也是有出現可能的,比如IOS裡使用了C++代碼,C++部分的對象是不會有ARC來管理的。
EXC_BAD_ACCESS錯誤不像訪問null 指標一樣容易定位,往往報錯時很難尋找到錯誤點,所以XCode在Instruments中提供了單獨的Zombies工具來分析這類錯誤。
使用Zombies分析的原理
和使用 Instruments的其他工具一樣,點擊XCode的Product菜單Profile啟動Instruments:
可以看到Zombies工具下邊的介紹,用於尋找那些被過度釋放的殭屍對象。
Zombies工具的尋找原理其實和設定NSZombieEnabled環境變數的調試方式是一樣的,啟動Zombies後在內部設定了NSZombieEnabled為True。
啟用了NSZombieEnabled的話,它會用一個殭屍來替換預設的dealloc實現,也就是在引用計數降到0時,該殭屍實現會將該對象轉換成殭屍對象。殭屍對象的作用是在你向它發送訊息時,就不會向之前那樣Crash或者產生 一個難以理解的行為,而是放出一個錯誤訊息,它會顯示一段日誌並自動跳入調試器, 因此我們就可以找到具體或者大概是哪個對象被錯誤的釋放了。
使用Zombies分析的步驟
1、啟動Instruments,選擇Zombies;
2、對之前產生EXC_BAD_ACCESS的測試案例重新運行,直到程式崩潰,如果發生EXC_BAD_ACCESS錯誤,會出現以下介面:
3、通過滑動箭頭來查看錯誤細節,例如可以看到該對象的記憶體操作過程,如malloc、autorelease、retain、release等操作;
4、查看底部的詳細曆史,選擇相應的行可以定位到相應的代碼,找出產生錯誤的代碼:
基本上通過查看Zombies工具給出的資訊找出錯誤碼行是比較簡單的,Zombies也只有在產生EXC_BAD_ACCESS錯誤時才有用。
手動設定NSZombieEnabled環境變數:
XCode也提供了手動設定NSZombieEnabled環境變數的方法,不過設定NSZombieEnabled為True後,會導致記憶體佔用的增長,同時會影響Leaks工具的調試,這是因為設定NSZombieEnabled會用殭屍對象來代替已釋放對象。
點擊Product菜單Edit Scheme開啟該頁面,然後勾選Enable Zombie Objects 複選框:
一般不建議進行進行手動設定,而應該使用Zombies工具進行調試。
記錄,為更好的自己!轉載請註明出處!