閱讀56 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Instruments使用小記(2012-11-28更新)

好記性不如爛筆頭,所以決定寫篇博客陸陸續續地記錄一些使用Instruments的技巧。


1. 內存泄露的檢測。

Memory Leak是編碼過程中最基本的一類問題,即請求了內存分配,卻沒有歸還給操作係統。

使用Instrument可以幫助我們進行內存泄露的檢測,不過先想想,如果要我們來檢測內存泄露,會怎麼做呢?一種最直接的方法就是通過遍曆構造一張堆上的內存分配、引用圖,檢測每一塊內存是否有引用存在。如果沒有,則表示存在內存泄露;如果有,卻並不代表不是內存泄露。所以,Instruments並不能檢測出所有的內存泄露。

我們可以簡單地分配一塊內存,不釋放,來檢測內存泄露:

NSArray *array = [[NSArray alloc] initWithObjects:@"1", @"2", nil];

然後使用Instruments的Leak檢測功能,可以得到下圖:


橙色區域表示存在內存泄露,很顯眼。並且在下方會顯示出具體的代碼位置:


此時,我們可以打開Extended Detail視圖觀察具體的函數調用,確定分別在哪裏發生了泄露:


雙擊可以打開源文件(右上Xcode圖標可以通過Xcode打開源文件進行定位):


但是,並非所有類型的對象都可以被檢測出來,比如UI對象以及NSString,猜測是由於存在對這些資源的內部管理機製。

下麵的代碼,Instrument並不能檢測出內存泄露:

NSString *string = [[NSString alloc] initWithString:@"LeakString"];

UILabel *label = [[UILabel alloc] init];
label = nil;

UIButton *btn = [[UIButton alloc] init];


2. 使用Heapshot進一步觀察內存泄露。

如果有指針指向一片內存區域,但代碼無法再訪問到該指針;或者存在循環引用。這些情況下,Instrument都無法檢測出內存泄露。

不過Instruments提供了堆快照來進一步觀察:


理想情況下,我們進入一個ViewController,然後再退回來,如果得到合理分配和釋放的話,堆的增長應該是零(或者趨向零,因為有些資源可能iOS自己管理住了):


如果內配和釋放不合理的話,通常每次堆快照都會有所增長,並且在多次重複操作後,依然增長:


如果存在這種情況,就需要特別關注下。

同樣地,我們也可以通過Extended Detail視圖來查看此時的函數調用信息,確定這些增長發生在哪裏。


3. Zombie Messaged

訪問野指針。直接原因是通過指針釋放對象後,指針沒有置空;間接原因可能是過於隨意地使用autorelease的對象,係統釋放後,我們還訪問。關於什麼時候係統會釋放auto-released對象,可以參照我寫的這篇文章

- (void)zombieTest:(id)sender
{
    UILabel *label = [[UILabel alloc] init];
    [label release];
    [sender addSubview:label];
}

如上代碼,就會讓程序掛掉,而且有時候很難排查。這種情況可以通過Instruments的Zombie選項來跟蹤:


開啟最下麵的選項“Enable NSZombie detection”,然後跑一下程序:


同樣可以定位到相應的代碼:



4. Time Profiler

當我們發現App有點卡的時候,可以通過Time Profiler來看耗時在哪裏。

 

通過運行時間可以找出卡在哪裏,從而進行優化。

但耗時最多的並不一定就是App流暢性的瓶頸。舉個例子,我之前寫了一個瀑布流控件(相關博文),在實現cell重用機製的基礎上,仍然發現滾動時候有點卡。於是我通過Time Profiler觀察,發現scrollViewDidScroll的耗時占比有點高,以為在滾動回調函數做的事情太多,我陷進了在相關代碼上死命尋找可優化的坑上,走上了過度優化的岔路。後來發現,是由於當時團隊成員修改了圖片異步加載相關代碼導致的。


5. 真機觀察Core Animation性能

通過聯調真機,可以觀察到運行時每秒繪製了多少幀(60幀封頂):

 

當幀率偏低時,就得注意優化了。

調試過程中,可以通過設置左側麵板的調試選項來獲得更多信息:


比如上圖中,我們勾選了“Color Blended Layers”選項,可以得到如下紅綠分布圖:


其中綠色代表不透明部分,紅色代表透明部分。紅色部分越多,對性能影響也越大,因為GPU需要對這些透明部分進行特殊處理(重複繪製)。

從上麵的幀率以及紅綠分布來看,湖畔這款App的性能還是不錯的。


[To be continued...]


最後更新:2017-04-02 16:47:36

  上一篇:go Android TextView顯示文字過長時添加陰影漸變消失效果
  下一篇:go SQL Server 2005無法遠程連接的解決方法