iOS啓動優化之二進制重排

隨着iOS項目愈來愈大,啓動時間也會變得愈來愈慢,咱們如何來對app的啓動時間來進行優化,給用戶一個更好的體驗呢?xcode

應用啓動介紹

應用啓動分爲冷啓動和熱啓動安全

  • 冷啓動是指內存中不存在與應用相關的數據,須要從硬盤時將應用的數據載入到內存中;這個過程是由系統決定的,平時咱們把應用殺死,而後立刻啓動,此時內存中的應用相關的數據不會立刻被清除,因此這時候的啓動不是冷啓動;
  • 熱啓動是指內存中還存留着應用相關的數據,應用運行所須要的數據不須要所有從硬盤中載入內存。

監控啓動時間

咱們能夠經過設置環境變量來起到監控應用啓動時間的目的,有關環境變量的設置,請參考Xcode環境變量markdown

咱們設置環境變量DYLD_PRINT_STATISTICS,運行工程,打印應用啓動時的時間消耗狀況: 多線程

打印出應用啓動時間以下: app

咱們以main函數爲分隔點,將應該啓動時間優化分爲main函數以前和main函數以後,這裏所打印的pre-main time就是main函數以前的耗時。函數

  • dylib loading time:動態庫的載入耗時,蘋果建議項目中自定義的動態庫最好不要超過6個動態庫,若是超過了6個要考慮動態庫合併;
  • rebase/binding time:偏移修正(rebase)和符號綁定(binding)的耗時;偏移修正是一個安全機制--ASLR,原理是生成一個隨機值,加到應用內存地址的前面,來起到方法、函數的地址隨機的目的,解決安全問題.全部的方法、函數和數據的內存地址都會在原有的真實地址上加上這個隨機值,而且每次啓動的時候這個隨機值是不一樣的,這樣別人就無法拿到方法、函數或數據的真實地址了;符號綁定是指將方法名與方法的實現,即sel和IMP的綁定。
  • ObjC setup time:Object-C類的註冊的耗時;不權威統計,每增長20000個類,這個時間增長800ms;減小類的數量能夠減小啓動耗時;
  • initializer time:load方法和構造方法的耗時.因此項目中要儘可能減小重寫load 方法,將load方法的操做放在initialization中.

以上就是main函數以前的啓動耗時說明及相關優化方案;post

對於main函數以後的啓動耗時,咱們能夠經過代碼的方式進行監控,好比,在main函數中記錄一個時間,到第一個界面顯示的viewDidLoad方法中記錄一個時間,兩個時間的差值就是main函數以後的啓動耗時.因爲main函數以後的耗時須要根據不一樣的項目來區分,不能一律而論,這裏提供幾個優化的建議優化

  • 減小數據的加載,最好使用懶加載,如一個第三文庫的加載;
  • 將項目中再也不使用的類和方法去掉;
  • 使用多線程技術加載數據,充分利用cpu的資源;
  • 啓動時刻的界面,不要使用storyboard或xib,儘可能使用純代碼,由於storyboard或xib有一步代碼轉換的操做,也是會耗時的。

二進制重排

技術背景

應用程序在運行時,使用的是虛擬內存與物理內存相結合的方法加載數據的;虛擬內存是分頁管理的,當使用到某一頁虛擬內存的數據時,須要將對應的真實數據加載到物理內存中,將虛擬內存與物理內存以前造成一個映射關係,這個操做稱爲缺頁異常(page fault),這個操做是需耗時的。spa

查看iOS應用的載入數據的順序,咱們能夠經過設置Write Link Map File爲yes,來查看應用數據加載的順序 線程

clean一下工程,而後command+B編繹一下工程,來到Products的xx.app目錄下

再來到以下目錄下

找到以下文件

打開此文件Demo-LinkMap-normal-x86_64.txt

這裏的順序就是應用數據加載的順序,這裏的順序是由下以兩個因素決定的

按文件順序從上到下

按文件中的方法的順序從上到下

驗證一下此文件的順序就是實際的載入順序,能夠經過修改文件或方法的順序,而後從新編繹後查看link map文件的方法順序是否改變。

二進制重排方案

因爲咱們在應用在啓動時可能只須要某些文件中的某些方法,而按照實際的方法載入順序,在應用啓動時會由於page fault的存在,就須要載入大量的用不到的數據,形成了大量的時間消耗,爲此咱們只須要在應用啓動時只載入啓動時須要的方法就能夠了,其實的數據能夠後續載入;爲此咱們能夠經過建立一個.order文件來修改方法或函數的加載順序.

打開hank.order文件,查看如下幾個方法的順序

將此文件配置到對應的xcode工程中

clean後從新編繹,查看Demo-LinkMap-normal-x86_64文件

這樣咱們就成功的修改了方法或函數的加載順序,因此咱們只須要知道應用啓動時執行了哪些方法,將他們排序好,放在.order文件中,就能夠在應用啓動時,只加載了本身須要的數據,減小了page fault的次數,從而減小了啓動耗時。

那麼如何知道應用啓動時執行了哪些方法呢?請看Hook一切的終極武器--Clang插樁

相關文章
相關標籤/搜索