E-moss,程序員,愛好閱讀和擼狗,主要從事iOS開發工做,公衆號:知本集。
主要分享和編寫技術方面文章,不按期分享讀書筆記,亦可訪問「知本集」Git地址:https://github.com/knowtheroot/KnowTheRoot_iOS,歡迎提出問題和討論。
複製代碼
Git地址:github.com/knowtheroot…git
當咱們向系統申請內存時,系統並不會直接返回物理內存的地址,而是返回一個虛擬內存地址。從系統角度來講,每個進程都有相同大小的虛擬內存空間。
只有當進程開始使用申請到的虛擬內存時,系統纔會將虛擬地址映射到物理地址上,從而讓程序使用真實的物理內存。程序員
當A進程佔用了大部份內存,此時B進程須要內存時發現內存不足,系統則會通知App,讓App清理內存,既咱們熟知的Memory Warning。github
虛擬內存也有一樣的缺點:硬盤的容量比內存大,但也只是相對的,速度卻很是緩慢,若是和硬盤之間的數據交換過於頻繁,處理速度就會降低,表面上看起來就像卡住了同樣,這種現象稱爲抖動(Thrushing)。相信不少人都有過計算機中止響應的經歷,而形成死機的主要緣由之一就是抖動。bash
iOS系統會對虛擬內存和物理內存進行分頁,虛擬內存到物理內存的映射都是以頁爲最小粒度的。數據結構
將虛擬內存空間和物理內存空間皆劃分爲大小相同的頁面,如4kb、8kb或16kb等。並以頁面做爲內存空間的最小單位,一個程序的一個頁面能夠存放在任意一個物理頁面裏。ide
系統將內存頁分爲三個狀態:
(1)活躍的內存頁(active page):內存頁已經被映射到物理內存中,並且近期被訪問過,處於活躍狀態。
(2)非活躍的內存頁(inactive page):內存頁已經被映射到物理內存中,可是近期沒有被訪問過。
(3)可用的內存頁(free page):沒有關聯到虛擬內存頁的物理內存頁集合。函數
當可用的內存頁下降到必定的閥值時,系統就會採起低內存應對措施,在OSX中,系統會將非活躍內存頁交換到硬盤上,而在iOS中,則會觸發Memory Warning,若是你的App沒有處理低內存警告而且還在後臺佔用太多內存,則有可能被殺掉。優化
頁表的功能是提供虛擬頁面到物理頁面的映射。
頁表的記錄條數與虛擬頁面數相同。此外,內存管理單元依賴於頁表來進行一切與頁面有關的管理活動,這些活動包括判斷某一頁面號是否在內存裏,頁面是否受到保護,頁面是否非法空間等等。
因爲頁表的特殊地位,決定了它是由硬件直接提供支持,即頁表是一個硬件數據結構。spa
爲了更好的管理內存頁,系統將一組連續的內存頁關聯到一個VMObject上。
VMObject主要包含如下屬性:指針
堆區會被劃分紅不少不一樣的VM Region,不一樣類型的內存分配根據需求進入不一樣的VM Region。
OC中,除了使用NSObject的alloc分配內存外,還可使用c的函數malloc進行內存分配。malloc的內存分配固然也是先分配虛擬內存,而後使用的時候再映射到物理內存,不過malloc有一個缺陷,必須配合memset將內存區中全部的值設置爲0。這樣就致使了一個問題,malloc出一塊內存區域時,系統並無分配物理內存。然而,調用memset後,系統將會把malloc出的全部虛擬內存關聯到物理內存上,由於你訪問了全部內存區域。
爲了解決這個問題,蘋果官方推薦使用calloc代替malloc,calloc返回的內存區域會自動清零,並且只有使用時纔會關聯到物理內存並清零。
calloc和malloc 主要的區別在於前者在返回內存的指針以前將它初始化爲0,另外它們請求數量的方式不一樣。calloc的參數包括所需元素的數量和每一個元素的字節,根據這些值能夠計算出總共須要分配的內存空間(num_elements*element_size)個字節。