iOS APP性能檢測(cè)&優(yōu)化(一)

性能優(yōu)化,都要優(yōu)化什么稚配?

  • 啟動(dòng)時(shí)間
  • 內(nèi)存
  • 刷新幀率
  • UI阻塞次數(shù)奶赠,不可操作時(shí)長(zhǎng),主線程阻塞超過(guò)400毫秒次數(shù)
  • CPU使用率
  • GPU使用率
  • 網(wǎng)絡(luò)請(qǐng)求時(shí)間药有,流量消耗
  • 耗電功率

如何去監(jiān)測(cè)這些性能指標(biāo)毅戈。

  • Xcode自帶的Instrument Instrument 用戶指南(中文版)
    Instrument 性能檢測(cè)圖譜:

    Instrument 性能檢測(cè)圖譜.jpeg

  • 使用第三方SDK :Bugly苹丸、OneAPM、聽(tīng)云苇经、Firebase Analytics

  • 自行開(kāi)發(fā)檢測(cè)代碼

啟動(dòng)時(shí)間

1.通過(guò)Instrument的Time Profiler赘理,找到包含-[UIApplication _reportAppLaunchFinished]的最后一幀,可計(jì)算出啟動(dòng)時(shí)間扇单。

2.自行添加代碼計(jì)算
t1
系統(tǒng)dylib和自身app可執(zhí)行文件(app中所有.o文件的集合)的加載
Launch頁(yè)

t2
main()
UIApplicationMain()
willFinishLaunchingWithOptions()
didFinishLaunchingWithOptions()

t3
loadView()
viewDidLoad()
applicationDidBecomeActive()

啟動(dòng)時(shí)間 t = t1 + t2;
app從啟動(dòng)到打開(kāi)第一個(gè)頁(yè)面的時(shí)間 t = t1 + t2 + t3;

t1:在Xcode的Edit scheme中增加
DYLD_PRINT_STATISTICS這個(gè)環(huán)境變量商模,控制臺(tái)就會(huì)打印這個(gè)時(shí)間。


launch time.png

t2蜘澜、t3都可以通過(guò)埋點(diǎn)的方式添加獲取時(shí)間的代碼即可施流。

內(nèi)存

目前在開(kāi)發(fā)的階段只會(huì)注意內(nèi)存泄露和內(nèi)存異常兩種情況,具體的內(nèi)存分配鄙信、僵尸對(duì)象等可能會(huì)在開(kāi)發(fā)結(jié)束后進(jìn)行檢測(cè)瞪醋。

內(nèi)存泄露除了使用instrument,還有:

  • 手動(dòng)添加代碼:
- (void)delloc {
      NSLog(@"------------->--->%@被釋放了",[self class]);
}

這個(gè)只是說(shuō)明某個(gè)類釋放情況装诡,并不能定位到具體代碼银受,需要在類內(nèi)部進(jìn)行排查。

  • 第三方工具M(jìn)LeaksFinder鸦采,優(yōu)點(diǎn):
    1.這個(gè)庫(kù)不需要入侵項(xiàng)目代碼宾巍,直接pod導(dǎo)入一下庫(kù)就
    2.不用像instruments那么麻煩,還需要自己來(lái)仔細(xì)觀察
    3.庫(kù)只在debug狀態(tài)運(yùn)行渔伯,完全不影響app打包大小

內(nèi)存異常就只是觀察Xcode里面的內(nèi)存顯示或者埋點(diǎn)插入內(nèi)存計(jì)算的方法顶霞,代碼如下:

#import <mach/mach.h>
#import <mach/task_info.h>

- (unsigned long)memoryUsage
{
    struct task_basic_info info;
    mach_msg_type_number_t size = sizeof(info);
    kern_return_t kr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);  
    if (kr != KERN_SUCCESS) {    
        return -1;
    }
    unsigned long memorySize = info.resident_size >> 10;//10-KB   20-MB   

    return memorySize;
//返回的數(shù)值單位是KB,如果想要MB的話把10改為20锣吼。
}

刷新幀率
刷新幀率利用CADisplayLink做一個(gè)小工具進(jìn)行檢測(cè)确丢,查看認(rèn)識(shí)并使用CADisplayLink

UI阻塞次數(shù)吐限,不可操作時(shí)長(zhǎng)鲜侥,主線程阻塞超過(guò)400毫秒次數(shù)

美團(tuán)移動(dòng)端性能監(jiān)控方案Hertz
在實(shí)踐中采用的是檢測(cè)主線程每次執(zhí)行消息循環(huán)的時(shí)間,當(dāng)這一時(shí)間大于閾值時(shí)诸典,就記為發(fā)生一次卡頓描函。

卡頓檢測(cè).png

開(kāi)辟一個(gè)子線程,然后實(shí)時(shí)計(jì)算 kCFRunLoopBeforeSources 和 kCFRunLoopAfterWaiting 兩個(gè)狀態(tài)區(qū)域之間的耗時(shí)是否超過(guò)某個(gè)閥值狐粱,來(lái)斷定主線程的卡頓情況舀寓。這個(gè)還是比較準(zhǔn)確的數(shù)據(jù)。
但是由于主線程的RunLoop在閑置時(shí)基本處于Before Waiting狀態(tài)肌蜻,這就導(dǎo)致了即便沒(méi)有發(fā)生任何卡頓互墓,這種檢測(cè)方式也總能認(rèn)定主線程處在卡頓狀態(tài)。

CPU使用率
CPU使用率只需觀察Xcode里面的數(shù)據(jù)或者埋點(diǎn)插入CPU使用率計(jì)算的方法蒋搜,代碼如下:

- (float)cpu_usage
{
    kern_return_t            kr = { 0 };
    task_info_data_t        tinfo = { 0 };
    mach_msg_type_number_t    task_info_count = TASK_INFO_MAX;

    kr = task_info( mach_task_self(), TASK_BASIC_INFO, (task_info_t)tinfo, &task_info_count ); 
    if ( KERN_SUCCESS != kr )   
        return 0.0f;

    task_basic_info_t        basic_info = { 0 };
    thread_array_t            thread_list = { 0 };
    mach_msg_type_number_t    thread_count = { 0 };

    thread_info_data_t        thinfo = { 0 };
    thread_basic_info_t        basic_info_th = { 0 };

    basic_info = (task_basic_info_t)tinfo;    // get threads in the task
    kr = task_threads( mach_task_self(), &thread_list, &thread_count ); 
    if ( KERN_SUCCESS != kr )   
        return 0.0f;  
    long    tot_sec = 0;  
    long    tot_usec = 0;  
    float    tot_cpu = 0;  
    for ( int i = 0; i < thread_count; i++ )
    {
        mach_msg_type_number_t thread_info_count = THREAD_INFO_MAX;

        kr = thread_info( thread_list[i], THREAD_BASIC_INFO, (thread_info_t)thinfo, &thread_info_count );   
         if ( KERN_SUCCESS != kr )       
              return 0.0f;

        basic_info_th = (thread_basic_info_t)thinfo;   
         if ( 0 == (basic_info_th->flags & TH_FLAGS_IDLE) )
        {
            tot_sec = tot_sec + basic_info_th->user_time.seconds + basic_info_th->system_time.seconds;
            tot_usec = tot_usec + basic_info_th->system_time.microseconds + basic_info_th->system_time.microseconds;
            tot_cpu = tot_cpu + basic_info_th->cpu_usage / (float)TH_USAGE_SCALE;
        }
    }

    kr = vm_deallocate( mach_task_self(), (vm_offset_t)thread_list, thread_count * sizeof(thread_t) );  
           if ( KERN_SUCCESS != kr )    
               return 0.0f;   
            return tot_cpu * 100.; // CPU 占用百分比}

具體使用可以使用instrument查看篡撵。

GPU使用率
iOS 設(shè)備跟蹤 GPU 使用率
GPUUtilization GPU使用率檢測(cè)Demo

網(wǎng)絡(luò)請(qǐng)求時(shí)間判莉,流量消耗
該部分在AFNetworking研究之后再做補(bǔ)充。

鏈接文章:
iOS APP性能檢測(cè)&優(yōu)化(二)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末育谬,一起剝皮案震驚了整個(gè)濱河市券盅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌膛檀,老刑警劉巖锰镀,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異咖刃,居然都是意外死亡泳炉,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)嚎杨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)花鹅,“玉大人,你說(shuō)我怎么就攤上這事磕潮〈湟龋” “怎么了容贝?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵自脯,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我斤富,道長(zhǎng)膏潮,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任满力,我火速辦了婚禮焕参,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘油额。我一直安慰自己叠纷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布潦嘶。 她就那樣靜靜地躺著涩嚣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪掂僵。 梳的紋絲不亂的頭發(fā)上航厚,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音锰蓬,去河邊找鬼幔睬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛芹扭,可吹牛的內(nèi)容都是我干的麻顶。 我是一名探鬼主播赦抖,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼澈蚌!你這毒婦竟也來(lái)了摹芙?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤宛瞄,失蹤者是張志新(化名)和其女友劉穎浮禾,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體份汗,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盈电,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了杯活。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匆帚。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖旁钧,靈堂內(nèi)的尸體忽然破棺而出吸重,到底是詐尸還是另有隱情,我是刑警寧澤歪今,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布嚎幸,位于F島的核電站,受9級(jí)特大地震影響寄猩,放射性物質(zhì)發(fā)生泄漏嫉晶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一田篇、第九天 我趴在偏房一處隱蔽的房頂上張望替废。 院中可真熱鬧,春花似錦泊柬、人聲如沸椎镣。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)状答。三九已至,卻和暖如春闸氮,著一層夾襖步出監(jiān)牢的瞬間剪况,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工蒲跨, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留穗熬,地道東北人土至。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓毅该,卻偏偏與公主長(zhǎng)得像备绽,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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