啟動優化-概念與建議

基本概念

虛擬內存&物理內存

  • 早期的數據訪問是直接通過物理地址訪問的,這種方式有以下兩種問題
    • 內存不夠用
    • 內存數據的安全問題

內存不夠用解決方案:虛擬內存

  • 我們在進程和物理內存之間增加一個中間層,這個中間層就是所謂的虛擬內存,主要用於解決當多個進程同時存在時,對物理內存的管理。提高CPU的使用率,使多個進程可以同時按需求加載,而虛擬內存的本質是一張虛擬地址亂以地址的對應關係映射表。
  • 每個進程都有一個獨立的虛擬內存。其地址都是從0開始,大小是4G固定的,每個虛擬內存又會劃分一個一個的頁(頁的大小在iOS中是16K,其他是4K),每次加載都是以頁為單位加載的,進程間無法互相訪問的,也保證了數據的安全性。
  • 一個進程中,只有部分功能是活躍的,所以只需要將進程中活躍的部分放入物理內存,避免物理內存的浪費
  • 當CPU需要訪問數據時,首先是訪問虛擬內存,然後通過虛擬內存去尋址,即可以理解為在表中找對應的物理地址然後相對應的物理地址進行訪問
  • 如果再訪問時,虛擬地址的內容為加載到物理內存,會發生缺頁異常(pagefault),將當前進程阻塞掉,此時需要先將數據載入到物理內存,然後在尋址,進行讀取。這樣就避免了內存浪費

如下圖所示,虛擬內存與物理內存間的關係

123.png

內存數據的安全問題:ASLR技術

  • 我們了解到虛擬內存的起始地址與大小都是固定的,意味著,當我們訪問數據地址時也是固定的,這會導致我們的數據非常容易被破解,為了解決這個問題,所以蘋果為了解決這個問題,在iOS4.3開始引入ASLR技術。
  • ASLR概念(Address Space Layout Randomization )地址空間配置隨機加載,是一種針對緩衝區溢出安全保護技術,通過對堆,棧,共享庫映射等線性區佈局的隨機化,通過增加攻擊者預測目的的地址的難度,防止攻擊者直接定位攻擊代碼位置,達到阻止溢出攻擊的目的的一種技術。其目的是通過利用隨機方式配置數據地址空間,使某些敏感數據(例如APP登入註冊,支付相關代碼)配置到一個惡意程序無法事先獲知的地址,令攻擊者難以進行攻擊
  • 由於ASLR的存在,導致可執行文件和動態鏈接庫在虛擬內存中的加載地址每次啟動都不固定,所以需要在編譯時來修復鏡像中的資源指針,來指向正確的地址,即正確的內存地址= ASLR + 偏移值

優化建議

冷啟動/熱啟動

  • 從用戶點擊app的iconAppDelegate的didFinishLaunching方法執行完成為止稱之為啟動的過程 ,然而啟動也分為了冷啟動和熱啟動。
    • 冷啟動:內存中不包含app相關數據的啟動,一般我們可以通過重啟手機來實現冷啟動。
    • 熱啟動:當app退到後台(即按下home鍵),app還存在一段時間,這時點擊app馬上能恢復到原狀態(即數據還在內存),這種稱之為熱啟動。
  • 接下來探討的啟動優化則是屬於冷啟動 ,這個啟動主要分為兩個部分
    • T1:pre-main階段,即main函數之前,操作系統加載App可執行文件到內存,執行一系列的加載以及鏈接等工作,簡單來說,就是dyld加載過程。
    • T2:main函數之後,即從main函數開始,到Appdelegate的didFinishLaunching 方法執行完成為止主要是構建第一個介面,並完成渲染。

dyld 加載流程

所以,T1+T2的過程就是從用戶點擊App圖標到用戶能看到App主界面的過程,即需要啟動優化的部分。

pre-main階段的優化

  • 在dyld加載過程中,已經了解過了dyld加載流程。pre-main階段的啟動時間其實就是dyld加載過程的時間
  • 對於main函數之前的啟動時間,平過提供了內建的檢測方法,Edit Scheme → Run → Argument → Enviroment Variables點擊+添加環境變量DYLD_PRINT_STATISTICS ,然後運行 以下是iPhone8plus 正常冷啟動的pre-main時間(以Wechat為例)。

內容說明

pre-main階段總共用時1.7s

  • dylib loading time (動態庫耗時) : 主要是加載動態庫共使用了175.11ms
  • rebase/binding time(偏移修正/符號綁定耗時),耗時160.52ms
    • rebase(偏移修正):任何一個app生成的二進制文件,在二進制文件內部所有的方法,函數調用,都有一個地址,這個地址是在當前二進制文件中的偏移地址。一旦在運行時刻(即運行到內存中),每次系統都會隨機分配一個ASLR(Address Space Layout Randomization,地址空間隨機加載化)地址值(是一個安全機制,會分配一個隨機的數值,插入在二進制文件的開頭),例如,二進制文件中有一個test方法,偏移值是0x0001,而隨機分配的ASLR是0x1ff0,如果想訪問test方法,其內存地址(真實地址)變為ASLR+偏移值 = 運行時確定的內存地址(即0x1ff0+0x0001=0x1ff1)
    • binding(綁定):例如NSLog方法,在編譯時期生成的mach-O文件中,會創建一個符號!NSLog(指向一個隨機地址),在運行時(從瓷盤加載到內存中,是一個鏡像文件),會將真正的地址給符號(即在內存中將地址與符號進行綁定,是dyld做的,也稱為動態庫符號綁定),一句話概括:綁定就是符號賦值的過程
  • Objc setup time (OC類註冊的耗時):OC類越多,越耗時
  • initializer time (執行load和構造函數的耗時)

針對以上幾點,有以下優化建議

  • 盡量少用外部動態庫,蘋果官方建議自定義的動態庫最好不要超過六個,如果超過六個需要合併動態庫
  • 減少OC類,因為OC類越多,越耗時
  • 將不必須在+load方法中做的事情延遲到+initialize中,盡量不要用c++虛函數
  • 如果是swift,盡量使用struct

main函數階段的優化

  • 在main函數之後的didFinishLaunching 方法中,主要執行了各種業務,有很多並不是必須在這裡立即執行,這種業務我們可以採取延遲加載,防止影像啟動時間
  • didFinishLaunching中的業務主要分為三個類型
    • 第一類:初始化第三方sdk
    • 第二類:app運行環境配置
    • 第三類:自己工具類的初始化

main函數階段的優化建議主要有以下幾點:

  • 減少啟動初始化的流程,能懶加載的懶加載,能延遲的延遲,能放後台初始化的放後台,盡量不要佔用主線程的啟動時間。
  • 優化代碼邏輯,去除非必須的代碼邏輯,減少每個流程的消耗時間
  • 啟動階段能使用多線程來初始化的,就使用多線程
  • 盡量使用纯代碼來進行UI框架的搭建,尤其是主UI框架,例如UITabBarController。盡量避免使用Xib或者Storyboard,相比純代碼而言,這種更耗時
  • 刪除廢棄的類和方法
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容