(1)管理方式:堆中資源由程序員控制(通過malloc/free、new/delete,容易產生memory leak),棧資源由編譯器自動管理。
(2)系統響應:對於堆,系統有一個記錄空閑內存地址的鏈表,當系統收到程序申請時,遍歷該鏈表,尋找第一個大於所申請空間的空間的堆結點,刪除空閑結點鏈表中的該結點,並將該結點空間分配給程序(大多數系統會在這塊內存空間首地址記錄本次分配的大小,這樣delete才能正確釋放本內存空間,另外,系統會將多余的部分重新放入空閑鏈表中)。對於棧,只要棧的剩余空間大於所申請空間,系統就會為程序分配內存,否則報異常出現棧空間溢出錯誤。
(3)空間大小:堆是不連續的內存區域(因為系統是用鏈表來存儲空閑內存地址的,自然不是連續),堆的大小受限於計算機系統中有效的虛擬內存(32位機器上理論上是4G大小),所以堆的空間比較靈活,比較大。棧是一塊連續的內存區域,大小是操作系統預定好的,windows下棧大小是2M(也有是1M,在編譯時確定,VC中可設置)。
(4)碎片問題:對於堆,頻繁的new/delete會造成大量內存碎片,降低程序效率。對於棧,它是一個先進后出(first-in-last-out)的結構,進出一一對應,不會產生碎片。
(5)生長方向:堆向上,向高地址方向增長;棧向下,向低地址方向增長。
(6)分配方式:堆是動態分配(沒有靜態分配的堆)。棧有靜態分配和動態分配,靜態分配由編譯器完成(如函數局部變量),動態分配由alloca函數分配,但棧的動態分配資源由編譯器自動釋放,無需程序員實現。
(7)分配效率:堆由C/C++函數庫提供,機制很復雜,因此堆的效率比棧低很多。棧是機器系統提供的數據結構,計算機在底層對棧提供支持,分配專門的寄存器存放棧地址,提供棧操作專門的指令。