時間分析器
你要看的第一個工具是 Time Profiler
。在測量的時間間隔內,Instruments 將停止程式的執行並在每個執行的執行緒上執行堆疊跟蹤。把它想象成按下 Xcode 偵錯程式中的暫停按鈕。這是 Time Profiler 的預覽: -
此螢幕顯示 Call Tree
。Call Tree
顯示了在應用程式中以各種方法執行所花費的時間。每行都是程式執行路徑所遵循的不同方法。在每種方法中花費的時間可以根據每種方法中分析器停止的次數來確定。例如,如果以 1 毫秒的間隔完成 100 個樣本,並且發現特定方法位於 10 個樣本中的堆疊頂部,那麼你可以推斷出總執行時間的大約 10% - 10 毫秒 - 花費了在那種方法中。這是一個相當粗略的近似,但它的工作原理! **** **** ****
從 Xcode’s
選單欄中選擇 Product\Profile
或 press ⌘I
。這將構建應用程式並啟動儀器。你將看到一個如下所示的選擇視窗:
這些都是儀器附帶的不同模板。
選擇 Time Profiler
儀器,然後單擊選擇。這將開啟一個新的 Instruments 文件。單擊左上角的紅色記錄按鈕開始錄製並啟動應用程式。可能會要求你輸入密碼以授權儀器分析其他過程 - 不要擔心,這裡提供是安全的! 在“ 儀器”視窗中,你可以看到計時的時間,以及在螢幕中心的圖形上方從左向右移動的小箭頭。這表明該應用正在執行。
現在,開始使用該應用程式。搜尋一些影象,並深入檢視一個或多個搜尋結果。你可能已經注意到,進入搜尋結果的速度非常慢,滾動瀏覽搜尋結果列表也非常煩人 - 這是一個非常笨重的應用程式!
嗯,你很幸運,因為你即將開始修復它! 但是,你首先要快速瞭解你在 Instruments 中所看到的內容。首先,確保工具欄右側的檢視選擇器同時選擇了兩個選項,如下所示:
這將確保所有面板都是開放的。現在研究下面的截圖以及它下面每個部分的解釋:
1. 這些是記錄控制。紅色記錄按鈕將在單擊時停止並啟動當前正在分析的應用程式(它在記錄和停止圖示之間切換)。暫停按鈕完全符合你的預期,並暫停當前應用程式的執行。
2. 這是執行定時器。計時器計算正在執行的應用程式執行的時間長度以及執行的次數。如果你停止然後使用錄製控制元件重新啟動應用程式,那將啟動一個新的執行,然後顯示將顯示 2 的第 2 跑。
3. 這就是所謂的軌道。對於你選擇的 Time Profiler 模板,只有一個儀器,因此只有一個軌道。你將在本教程後面的內容中詳細瞭解該圖的具體細節。
4. 這是細節面板。它顯示了你正在使用的特定儀器的主要資訊。在這種情況下,它顯示的是最熱門的方法 - 也就是那些耗盡了大部分 CPU 時間的方法。如果單擊頂部顯示呼叫樹(左側)的欄並選擇樣本列表,則會顯示不同的資料檢視。此檢視顯示每個樣本。單擊幾個樣本,你將看到捕獲的堆疊跟蹤顯示在擴充套件詳細資訊檢查器中。
5. 這是檢查人員面板。有三個檢查員:記錄設定,顯示設定和擴充套件詳細資訊。你很快就會了解其中一些選項。
鑽深
執行影象搜尋,並深入檢視結果。我個人喜歡搜尋狗,但選擇你想要的任何東西 - 你可能是那些貓人之一!
現在,在列表中向上和向下滾動幾次,以便在 Time Profiler
中獲得大量資料。你應該注意到螢幕中間的數字在變化,圖形填滿了; 這告訴你正在使用 CPU 週期。
你真的不希望任何 UI 如此笨重,因為沒有 table view
準備發貨,直到它像黃油一樣滾動! 為了幫助查明問題,你需要設定一些選項。
在右側,選擇“ 顯示設定”檢查器 (or press ⌘+2)
。在檢查器中,在 Call Tree
部分下,選擇“按執行緒分隔” ,反轉,隱藏丟失的符號和隱藏系統庫。它看起來像這樣:
以下是每個選項對左側表格中顯示的資料的作用:
按執行緒分開: 每個執行緒應單獨考慮。這使你可以瞭解哪些執行緒負責最大量的 CPU 使用。
反轉呼叫樹: 使用此選項,stack trace
從上到下進行考慮。這通常是你想要的,因為你希望看到 CPU 花費時間的最深層方法。
隱藏丟失的符號: 如果找不到你的應用或 system framework
的 dSYM
檔案,那麼你只需看到與二進位制內部地址對應的十六進位制值,而不是檢視錶中的方法名稱(符號)。如果選擇此選項,則僅顯示完全解析的符號,並隱藏未解析的十六進位制值。這有助於整理所呈現的資料。
隱藏系統庫: 選擇此選項後,僅顯示你自己的應用程式中的符號。選擇此選項通常很有用,因為通常你只關心 CPU 在你自己的程式碼中花費時間的位置 - 你無法對 system libraries
使用的 CPU 數量做多少工作 !
Flatten Recursion: 此選項將遞迴函式(自稱為自稱函式)視為每個 stack trace
中的一個條目,而不是多個。
頂部函式: 啟用此選項使得 Instruments
將函式中花費的總時間視為該函式中直接時間的總和,以及該函式呼叫的函式所花費的時間。
因此,如果函式 A 呼叫 B,則 A 的時間被報告為在 A PLUS 中花費的時間在 B 中花費的時間。這可能非常有用,因為它允許你在每次下降到呼叫堆疊時選擇最大的時間數字,歸零在你最耗時的方法。
如果你正在執行 Objective-C
應用程式,還可以選擇僅顯示 Obj-C :如果選擇此選項,則僅顯示 Objective-C
方法,而不是任何 C
或 C++
函式。你的程式中沒有,但如果你正在看一個 OpenGL
應用程式,它可能有一些 C++
,例如。
雖然某些值可能略有不同,但一旦啟用了上述選項,條目的順序應與下表類似:
嗯,這當然看起來不太好。絕大部分時間都用在將色調濾鏡應用於縮圖照片的方法中。這不應該對你造成太大的衝擊,因為表格載入和滾動是 UI 中最笨重的部分,而且當表格單元格不斷更新時。
要了解有關該方法中發生的更多資訊,請雙擊表中的行。這樣做會顯示以下檢視:
那很有意思,不是嗎! applyTonalFilter()
是一個在擴充套件中新增到 UIImage
的方法,在應用影象過濾器後花費了幾乎 100 %的時間用於建立 CGImage 輸出。
沒有太多可以做的事情來加快速度:建立影象是一個非常密集的過程,並且需要花費很長時間。讓我們試著退後一步,看看 applyTonalFilter()
的來源。單擊程式碼檢視頂部的痕跡路徑中的 Call Tree
返回上一個螢幕:
現在單擊表頂部 applyTonalFilter 行左側的小箭頭。這將展開呼叫樹以顯示 applyTonalFilter 的呼叫者。你可能還需要展開下一行; 在分析 Swift 時,呼叫樹中有時會出現重複的行,字首為 @objc。你對以應用程式的目標名稱(InstrumentsTutorial)為字首的第一行感興趣:
在這種情況下,此行引用結果集合檢視的 cellForItemAtIndexPath
。雙擊該行以檢視專案中的關聯程式碼。
現在你可以看到問題所在。應用音調濾波器的方法需要很長時間才能執行,並且它直接從 cellForItemAtIndexPath 呼叫,每當它要求過濾影象時,它將阻止 main thread
(以及整個 UI)。
分配
有關所有正在建立的物件和支援它們的記憶體的詳細資訊 ; 它還向你顯示每個物件的 retain counts
。要重新開始使用新的 instruments profile
,請退出 Instruments 應用程式。這一次,構建並執行應用程式,並在 Navigators 區域中開啟 Debug Navigator。然後單擊 Memory 在主視窗中顯示記憶體使用情況的圖表:
這些圖表可幫助你快速瞭解應用的效果。但是你需要更多的力量。單擊 Profile in Instruments
按鈕然後轉移以將此會話帶入儀器。該分配儀器會自動啟動。
這次你會注意到兩個曲目。一種稱為分配,一種稱為洩漏。分配軌道將在後面詳細討論; Leaks 軌道在 Objective-C 中通常更有用,本教程不會介紹。那你接下來要追查什麼錯誤?專案中隱藏著一些你可能不知道的東西。你可能聽說過記憶體洩漏。但你可能不知道的是,實際上有兩種洩漏:
真正的記憶體洩漏是一個物件不再被任何東西引用但仍被分配的東西 - 這意味著永遠不能重用記憶體。即使使用 Swift 和 ARC
來幫助管理記憶體,最常見的記憶體洩漏型別仍然存在。這是當兩個物件彼此持有強引用時,每個物件使另一個物件不被釋放。這意味著他們的記憶永遠不會釋放!
無限的記憶體增長是繼續分配記憶體並且永遠不會被釋放的機會。如果這種情況持續下去,那麼在某些時候,system’s memory
將被填滿,你手上會有很大的記憶問題。在 iOS 中,這意味著應用程式將被系統殺死。
在應用程式上執行 Allocations 工具後,在應用程式中進行五次不同的搜尋,但不會深入檢視結果。確保搜尋有一些結果! 現在讓應用程式等待幾秒鐘。
你應該已經注意到 Allocations 軌道中的圖形一直在上升。這告訴你正在分配記憶體。這個功能將引導你找到 unbounded memory growth
。
你要表演的是一個人。為此,請按名為 Mark Generation 的按鈕。你將在顯示設定檢查器的頂部找到該按鈕:
按下它,你會看到軌道上出現一個紅色標記,如下所示:
generation analysis
的目的是多次執行一個動作,並檢視記憶是否在 unbounded fashion
中增長。鑽成搜尋,等待影象載入了幾秒鐘,然後回到主介面。然後再次標記一代。對不同的搜尋重複執行此操作。經過一個鑽成幾個搜尋,儀器看起來像這樣:
此時,你應該開始懷疑。請注意你鑽取的每個搜尋的藍色圖表是如何上升的。嗯,那當然不好。但等一下,怎麼樣 memory warnings?
你知道那些,對吧? Memory warnings
是 iOS 告訴應用程式記憶體部門事情變得緊張的方式,你需要清除一些記憶體。
這種增長可能不僅僅是因為你的應用程式; 它可能是一種深藏在記憶中的東西。在指向任何一個之前,先給系統框架和你的應用程式一個清除記憶的機會。
通過選擇 Instruments 選單欄中的 Instrument\Simulate Memory Warning
或 simulator’s
選單欄中的 Hardware\Simulate Memory Warning
來模擬 memory warning
。你會注意到記憶體使用量略有下降,或者根本沒有下降。當然不會回到它應該的位置。所以在某個地方仍然存在無限的記憶體增長。
在每次迭代鑽取到搜尋之後標記生成的原因是你可以看到在每一代之間分配了哪些記憶體。看看細節面板,你會看到幾代人。