在棧上分配的內存系統會自動地爲其釋放,例如在函數結束時,局部變量將不復存在,就是系統自動清除棧內存的結果。但堆中分配的內存則否則:一切由你負責,即便你退出了new表達式的所處的函數或者做用域,那塊內存還處於被使用狀態而不能再利用。好處就是若是你想在不一樣模塊中共享內存,那麼這一點正合你意,壞處是若是你不打算再利用這塊內存又忘了把它釋放掉,那麼它就會霸佔你寶貴的內存資源直到你的程序退出爲止。 程序員
棧是機器系統提供的數據結構,計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。堆則是C/C++函數庫提供的,它的機制是很複雜的,例如爲了分配一塊內存,庫函數會按照必定的算法(具體的算法能夠參考數據結構/操做系統)在堆內存中搜索可用的足夠大小的空間,若是沒有足夠大小的空間(多是因爲內存碎片太多),就有可能調用系統功能去增長程序數據段的內存空間,這樣就有機會分到足夠大小的內存,而後進行返回。顯然,堆的效率比棧要低得多。
C/C++中,全部的方法調用都是經過棧來進行的,全部的局部變量,形式參數都是從棧中分配內存空間的。實際上也不是什麼分配,只是從棧頂向上用就行,就好像工廠中的傳送帶(conveyorbelt)同樣,StackPointer會自動指引你到放東西的位置,你所要作的只是把東西放下來就行.退出函數的時候,修改棧指針就能夠把棧中的內容銷燬.這樣的模式速度最快,固然要用來運行程序了.須要注意的是,在分配的時候,好比爲一個即將要調用的程序模塊分配數據區時,應事先知道這個數據區的大小,也就說是雖然分配是在程序運行時進行的,可是分配的大小多少是肯定的,不變的,而這個"大小多少"是在編譯時肯定的,不是在運行時. 看看LINUX內核源代碼的存儲管理部分,就知道操做系統是如何管理內存資源的。每一個進程都有獨立的地址空間,不過這只是虛地址,這也是咱們一般所看到的地址,因此咱們如今寫程序時不會像早期的程序員擔憂內存不夠用,對於LINUX用戶進程最大可用3G的地址空間,另外的1G留給內核。這裏討論的堆或棧都是在虛擬地址空間上,各個進程都有本身獨立堆、棧空間,不然,就象樓上一些哥們說的,一個進程飛了,那全部進程都得死。
至於堆和棧哪一個更快,從兩方面來考慮:1.分配和釋放,堆在分配和釋放時都要調用函數(MALLOC,FREE),好比分配時會到堆空間去尋找足夠大小的空間(由於屢次分配釋放後會形成空洞),這些都會花費必定的時間,具體能夠看看MALLOC和FREE的源代碼,他們作了不少額外的工做,而棧卻不須要這些。2.訪問時間,訪問堆的一個具體單元,須要兩次訪問內存,第一次得取得指針,第二次纔是真正得數據,而棧只需訪問一次。另外,堆的內容被操做系統交換到外存的機率比棧大,棧通常是不會被交換出去的。
綜上所述,站在操做系統以上的層面來看,棧的效率比堆高,對於應用程序員,這些都是透明的,操做系統作了不少咱們看不到的東西。算法