IOS開發基礎——內存的基礎探究(堆,棧)

小記

  • 靜態存儲區(全局存儲區)
  • 堆區
  • 棧區
  • 代碼區
  • 文字常量區

內存分區圖:程序員

內存分區圖
代碼區存放於低地址,棧區存放於高地址。區與區之間並非連續的。

app啓動後,代碼區,文字常量區,全局存儲區大小固定,指向這些區的指針不會產生崩潰性的錯誤。而堆區和棧區是時時刻刻變化的(堆的建立銷燬,棧的彈入彈出),當使用一個指針指向這兩個區的內存時,要注意內存是否已釋放,指向已經釋放的內存會產生野指針。數據結構

靜態存儲區(全局存儲區)

內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。它主要存放靜態數據、全局數據和常量。app

全局變量、靜態變量會存儲在此區域。事實上全局變量也是靜態的,所以,也叫全局靜態存儲區。函數

存儲方式:操作系統

  • 初始化的全局變量跟靜態變量放在一片區域(數據區)
  • 未初始化的全局變量與靜態變量放在相鄰的另外一片區域(BSS區)

程序結束後由系統釋放。指針

文字常量區

在程序中使用的常量存儲在此區域(常量字符串就是放在這裏的)。程序結束後,由系統釋放。在程序中使用的常量,都會到文字常量區獲取。cdn

代碼區

存放函數體的二進制代碼,運行程序就是執行代碼,代碼要執行就要加載進內存。對象

堆區

簡述

亦稱動態內存分配。程序在運行的時候用malloc或new申請任意大小的內存,程序員本身負責在適當的時候用free或delete釋放內存。動態內存的生存期能夠由咱們決定,若是咱們不釋放內存,程序將在最後才釋放掉動態內存(若是某動態內存再也不使用,須要將其釋放掉,不然認爲發生了內存泄漏現象)。blog

空間分配

動態分配和回收,不能靜態分配(堆區的地址是從低到高分配)。內存

分配步驟:

  • 操做系統有一個記錄空閒內存地址的鏈表
  • 當系統收到程序的申請時,會遍歷該鏈表,尋找第一個空間大於所申請空間的堆結點,而後將該結點從空閒結點鏈表中刪除,並將該結點的空間分配給程序
  • 因爲找到的堆結點的大小不必定正好等於申請的大小,系統會自動的將多餘的那部分從新放入空閒鏈表中

大小限制:

堆是向高地址擴展的數據結構,的內存區域因爲系統是用鏈表來存儲的空閒內存地址的,是不連續,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限於系統中有效的虛擬內存。因而可知,堆得到的空間比較靈活,也比較大。

特色

在堆中咱們不是按照進入堆的前後順序來提取元素,而是根據元素的優先級來提取元素,整體來講,堆是一種數據結構,它的插入和刪除的操做,要根據優先級來決定,同時堆也有以下幾個特性:

  1. 任意節點的優先級不小於它的子節點
  2. 任意節點的值都小於或者等於它的子節點
  3. 主要操做是插入和刪除它的最小元素(元素值自己就是優先級的鍵值,小元素享有高優先級) (每次取出優先級最高的元素,便是讓堆的最上層參與者退出堆)

由上面可看出堆的優勢是靈活方便,數據適應面普遍,可是效率有必定下降。[順序隨意]

棧區

簡述

在執行函數時,函數內局部變量的存儲單元均可以在棧上建立,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置於處理器的指令集中,效率很高,可是分配的內存容量有限。存儲的爲非靜態的局部變量,例如:函數參數,在函數中生命的對象的指針等。當系統的棧區大小不夠分配時, 系統會提示棧溢出。

空間分配

分配方式:(棧區地址從高到低分配),靜態分配(例如:局部變量的分配)和動態分配(例如,alloc函數進行分配)都由系統完成,不須要手動管理

分配步驟:

  • 存儲每個函數在執行的時候都會向操做系統索要資源,棧區就是函數運行時的內存。
  • 棧區中的變量由編譯器負責分配和釋放,內存隨着函數的運行分配,隨着函數的結束而釋放,由系統自動完成。

大小限制:

棧是向低地址擴展的數據結構,是一塊連續的內存的區域。是棧頂的地址和棧的最大容量是系統預先規定好的 ,若是申請的空間超過棧的剩餘空間時,將提示內存溢出。所以,能從棧得到的空間較小。

特色

只容許在連接串列或者陣列的一段(通常爲棧頂)進行加入數據(push)或者輸出數據(pop)。因爲棧只容許在一端進行操做,按照先進後出的原則來進行。 優勢是快速高效,缺點時有限制,數據不靈活。[先進後出]

棧的三個操做:

  1. Pop:取出棧中最上層的元素
  2. top:查看棧頂元素
  3. push:將一個新的元素放在棧的最上層。
相關文章
相關標籤/搜索