iOS性能分析和優(yōu)化工具Instruments

前言: 隨著項目的擴大和功能的增多,代碼沒有經(jīng)過嚴(yán)格的調(diào)試和優(yōu)化,要么任性地卡頓運行,要么就低調(diào)地崩潰,最后導(dǎo)致用戶用著不開心,開發(fā)者也比較煩惱。

為了突破這個這個關(guān)卡其實并不難,首先開發(fā)者只要在Xcode自帶的監(jiān)控調(diào)試工具 Instruments 上花點功夫就能夠讓代碼順暢運行。Instruments 提供了很多檢測功能,重點介紹一下我常用的幾大類:

Analyze—靜態(tài)分析

Leaks—內(nèi)存泄露(動態(tài)內(nèi)存泄露檢測)

Allocations:監(jiān)測內(nèi)存使用 / 分配情況

Time Profiler:檢測分析代碼的執(zhí)行時間。

(一)第一波基本概念

1.1.內(nèi)存空間的劃分: 我們知道,一個進程占用的內(nèi)存空間,包含5種不同的數(shù)據(jù)區(qū):(1)BSS段:通常是存放未初始化的全局變量;(2)數(shù)據(jù)段:通常是存放已初始化的全局變量。(3)代碼段:通常是存放程序執(zhí)行代碼。(4)堆:通常是用于存放進程運行中被動態(tài)分配的內(nèi)存段 , OC對象(所有繼承自NSObject的對象)就存放在堆里。(5)棧:由編譯器自動分配釋放,存放函數(shù)的參數(shù)值,局部變量等值。

棧內(nèi)存是系統(tǒng)來管理的,因此我們常說的內(nèi)存管理,指的是堆內(nèi)存的管理,也就是所有OC對象的創(chuàng)建和銷毀的管理。伴隨著iOS5的到來,蘋果推出了ARC(自動引用計數(shù))技術(shù),此模式下編譯器會自動在合適的地方插入retain、release、autorelease語句,也就是說編譯器會自動生成內(nèi)存管理的代碼,解放了廣大程序猿的雙手,也基本上避免了內(nèi)存泄露問題,但是呢...

1.2.內(nèi)存泄露: 百度百科給的定義是:"內(nèi)存泄漏也稱作'存儲滲漏',用動態(tài)存儲分配函數(shù)動態(tài)開辟的空間,在使用完畢后未釋放,結(jié)果導(dǎo)致一直占據(jù)該內(nèi)存單元。直到程序結(jié)束。(其實說白了就是該內(nèi)存空間使用完畢之后未回收)即所謂內(nèi)存泄漏"。在iOS應(yīng)用中的內(nèi)存泄露,原因一般有循環(huán)引用、錯用Strong/copy等。

(二)第二波( Instruments多功能檢測)

2.1. Analyze—靜態(tài)分析

顧名思義,靜態(tài)分析不需要運行程序,就能檢查到存在內(nèi)存泄露的地方。

1. 使用方法:打開Xcode,command + shift + B;或者Xcode - Product - Analyze;

2. 常見的三種泄露情形:

(1)創(chuàng)建了一個對象,但是并沒有使用。Xcode提示信息: Value Stored to 'number' is never read 。翻譯一下:存儲在'number'里的值從未被讀取過。

(2)創(chuàng)建了一個(指針可變的)對象,且初始化了,但是初始化的值一直沒讀取過。Xcode提示信息: Value Stored to 'str' during its initialization is never read

(3)調(diào)用了讓某個對象引用計數(shù)加1的函數(shù),但沒有調(diào)用相應(yīng)讓其引用計數(shù)減1的函數(shù)。Xcode提示信息: Potential leak of an object stored into 'subImageRef' 。 翻譯一下:subImageRef對象的內(nèi)存單元有潛在的泄露風(fēng)險。

2.2: Leaks—內(nèi)存泄露

Leaks是動態(tài)的內(nèi)存泄露檢查工具,需要一邊運行程序,一邊檢測。

1.使用方法: 進入Xcode,command + control + i ;或者Xcode - Xcode - Open Developer Tool - Instruments; 或者Xcode - Product - Profile。選擇Leaks。

一般用靜態(tài)分析檢查過的代碼,內(nèi)存泄露都比較少。測試了有3個項目能點的按鈕都點了,能進的頁面都進的,Leaks也沒檢測到泄露。

2.3. Allocations—內(nèi)存分配

Allocations是檢測程序運行過程中的內(nèi)存分配情況的,也需要同時運行著程序。

1.打開方法:同上。

2.界面情況如下:

2.4:Time Profiler 主要作用:分析代碼的執(zhí)行時間,以便找出導(dǎo)致程序變慢的原因。

當(dāng)點擊Time Profiler應(yīng)用程序開始運行后.就能獲取到整個應(yīng)用程序運行消耗時間分布和百分比.為了保證數(shù)據(jù)分析在統(tǒng)一使用場景真實行有如下點需要注意:

在開始進行應(yīng)用程序性能分析前,請一定要使用真機,因為模擬器運行在Mac上,然而Mac上的CPU往往比iOS設(shè)備要快。相反,Mac上的GPU和iOS設(shè)備的完全不一樣,模擬器不得已要在軟件層面(CPU)模擬設(shè)備的GPU,這意味著GPU相關(guān)的操作在模擬器上運行的更慢,尤其是使用CAEAGLLayer來寫一些OpenGL的代碼時候. 這就導(dǎo)致模擬器性能數(shù)據(jù)和用戶真機使用性能數(shù)據(jù)相去甚運.

另外在開始性能分析前,另外一件很重要的事情是,應(yīng)用程序一定要運行在Distribution 而不是Debug模式下.

在發(fā)布環(huán)境打包的時候,編譯器會引入一系列提高性能的優(yōu)化,例如去掉調(diào)試符號或者移除并重新組織代碼.另iOS引入一種Watch Dog[看門狗]機制.不同的場景下,“看門狗”會監(jiān)測應(yīng)用的性能。如果超出了該場景所規(guī)定的運行時間,“看門狗”就會強制終結(jié)這個應(yīng)用的進程.開發(fā)者可以crashlog看到對應(yīng)的日志.但Xcode在調(diào)試配置下會禁用Watch Dog.

如圖所示

相關(guān)配置項如下

Separate by Thread: 每個線程應(yīng)該分開考慮。只有這樣你才能揪出那些大量占用CPU的"重"線程

Invert Call Tree: 從上倒下跟蹤堆棧,這意味著你看到的表中的方法,將已從第0幀開始取樣,這通常你是想要的,只有這樣你才能看到CPU中話費時間最深的方法.也就是說FuncA{FunB{FunC}} 勾選此項后堆棧以C->B-A 把調(diào)用層級最深的C顯示在最外面

Hide Missing Symbols: 如果dSYM無法找到你的app或者系統(tǒng)框架的話,那么表中看不到方法名只能看到十六進制的數(shù)值,如果勾線此項可以隱藏這些符號,便于簡化數(shù)據(jù)

Hide System Libraries: 勾選此項你會顯示你app的代碼,這是非常有用的. 因為通常你只關(guān)心cpu花在自己代碼上的時間不是系統(tǒng)上的

Show Obj-C Only: 只顯示oc代碼 ,如果你的程序是像OpenGl這樣的程序,不要勾選側(cè)向因為他有可能是C++的

Flatten Recursion: 遞歸函數(shù), 每個堆棧跟蹤一個條目

Top Functions: 一個函數(shù)花費的時間直接在該函數(shù)中的總和,以及在函數(shù)調(diào)用該函數(shù)所花費的時間的總時間。

因此,如果函數(shù)A調(diào)用B,那么A的時間報告在A花費的時間加上B.花費的時間,這非常有用,因為它可以讓你每次下到調(diào)用堆棧時挑最大的時間數(shù)字,歸零在你最耗時的方法。如上做了相關(guān)配置之后會顯示如下圖所示情形

(三)第三波(小結(jié))

除了以上所描述常用instruments外,下面一些偶爾也會用到

Core Data:監(jiān)測讀取、緩存未命中、保存等操作,能直觀顯示是否保存次數(shù)遠(yuǎn)超實際需要。

Cocoa Layout:觀察約束變化,找出布局代碼的問題所在。 Network:跟蹤 TCP / IP 和 UDP / IP 連接。

Automations:創(chuàng)建和編輯測試腳本來自動化 iOS 應(yīng)用的用戶界面測試。

最后instruments只是一組工具,幫助我們分析代碼的工具,可能檢查的出的內(nèi)存問題和性能問題,肯定還是由代碼造成的。問題的本質(zhì)還是養(yǎng)成良好的代碼習(xí)慣,才是根本的解決方法。

首先是避免出現(xiàn)靜態(tài)分析里提到的三種常見內(nèi)存泄露問題,測試的好幾個項目里,都有出現(xiàn)類似的問題。在此有以下幾點tips:

tip1:哪些情況會增加App的內(nèi)存占用?(開發(fā)中未完成的項目)

(1) 創(chuàng)建對象,定義變量。

(2)調(diào)用一個函數(shù)或方法。

tip2:哪些情況會增加CPU的消耗?(bireme)

(1) 創(chuàng)建對象、調(diào)整對象屬性、銷毀對象。

(2)布局計算和Autolayout。

( 3)文本的計算和渲染。

( 4)圖片的解碼和繪制。 (用Time Profiler分析一下,可以更直觀地感受到哪些操作比較耗時,使用方法同上。)

tip3:

做好cell等可復(fù)用對象的重用;可以只創(chuàng)建一次的對象,不要創(chuàng)建多次(比如頁面的某個功能彈窗); 用較少的對象和方法調(diào)用去實現(xiàn)功能;將耗時的操作放在子線程等可以對內(nèi)存和性能做一些優(yōu)化 。

作者:Jcs_jun

鏈接:http://m.itdecent.cn/p/70eda135c256

來源:簡書

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容