天天看點

記憶體配置設定及堆與棧的差別1.記憶體配置設定方式2.程式的記憶體空間3.例子4 堆與棧的差別

記憶體配置設定方式有三種:

       1.從靜态存儲區域配置設定。記憶體在程式編譯的時候就已經配置設定好,這塊記憶體在程式的整個運作期間都存在。例如全局變量,static變量。

       2.從堆棧上配置設定。函數内的局部變量的存儲單元,函數執行結束時這些存儲單元自動被釋放。棧記憶體配置設定運算内置于處理器的指令集中,效率很高,但是配置設定的記憶體容量有限。

       3.從堆上配置設定,亦稱動态記憶體配置設定。程式在運作的時候用malloc或new申請任意多少的記憶體,程式員自己負責在何時用free或delete釋放記憶體。動态記憶體的生存期由程式員決定,使用非常靈活,但如果在堆上配置設定了空間,就有責任回收它,否則運作的程式會出現記憶體洩漏,頻繁地配置設定和釋放不同大小的堆空間将會産生堆内碎塊。

一個程式将作業系統配置設定給其運作的記憶體塊分為5個區域:

  1、棧區(stack):由編譯器自動配置設定釋放 ,存放為運作函數而配置設定的局部變量、函數參數、傳回資料、傳回位址等。其操作方式類似于資料結構中的棧。

  2、堆區(heap):一般由程式員配置設定釋放, 若程式員不釋放,程式結束時可能由OS回收 。配置設定方式類似于連結清單。

  3、靜态區,亦稱全局區。全局變量、靜态變量和常量都是存儲在該區的,程式結束後該區的變量由系統釋放。該區具體又可以三部分:

              1)已初始化的全局變量和靜态變量。

              2)未初始化的全局變量和靜态變量。

              3)常量資料區。

  4、文字常量區:程式代碼中使用的常量字元串,程式結束後由系統釋放。

  5、程式代碼區:存放函數體的二進制代碼。

4.1 申請方式

       stack: 由系統自動配置設定,是由編譯器自動管理,無需我們手工控制。

  heap: 需要程式員自己申請,并指明大小。對于堆來說,釋放工作由程式員控制,容易産生memory leak。

4.2 申請後響應

       stack:隻要棧的剩餘空間大于所申請空間,系統将為程式提供記憶體,否則将報異常提示棧溢出。

       heap:首先應該知道作業系統有一個記錄空閑記憶體位址的連結清單,當系統收到程式的申請時,會周遊該連結清單,尋找第一個空間大于所申請空間的堆結點,然後将該結點從空閑結點連結清單中删除,并将該結點的空間配置設定給程式。 

4.3 申請的空間大小

      stack:在 WINDOWS下,棧的大小是2M,由編譯器決定。

      heap:一般來講在32位系統下,堆記憶體可以達到4G的空間,從這個角度來看堆記憶體幾乎是沒有什麼限制的。

4.4 生長方式

      stack:棧是向低位址擴充的資料結構,是一塊連續的記憶體的區域。

      heap:向着記憶體位址增加的方向,是不連續的記憶體區域,系統使用連結清單來管理空閑的記憶體位址。

4.5 申請效率

      stack:由于棧是編譯器自動管理的,是以棧的申請效率高,但程式員無法控制。

      heap:堆由new或malloc動态申請,一般速度較慢,并且容易産生記憶體碎片。能被程式員控制,使用友善。

4.6 存儲内容

      stack:在函數調用時,第一個進棧的是主函數中後的下一條指令(函數調用語句的下一條可執行語句)的位址,然後是函數的各個參數,在大多數的C編譯器中,參數是由右往左入棧的,然後是函數中的局部變量。注意靜态變量是不入棧的。

  當本次函數調用結束後,局部變量先出棧,然後是參數,最後棧頂指針指向最開始存的位址,也就是主函數中的下一條指令,程式由該點繼續運作

     heap:一般是在堆的頭部用一個位元組存放堆的大小。堆中的具體内容有程式員安排。