操作系統中的堆棧區別

堆和棧是兩種內存分配的統稱。

一.棧

  • 棧會存放函數的局部變量,函數的返回地址等。棧有"LIFO"(後進先出)的特點。
  • 棧由操作系統分配,自動回收.
  • 棧的大小受到限制。在x86體系下,棧一般通過esp 指向棧幀頂部,ebp指向底部
  • 不斷的嵌套或者爲局部變量分配空間,可能導致棧溢出。這時候會觸發一個異常
  • 在執行完一個函數的時候,其中的變量都會從堆棧中彈出。
  • 無需親自管理內存,變量會自動分配和釋放。
  • 棧一般是高地址向低地址擴展,函數返回的時候,會通過返回原來的位置來釋放空間。
  • 棧對應的是CPU的一級緩存,一級緩存在CPU內部,訪問快,比較小

二.堆

  • 堆是計算機中不會自動管理的區域,不受CPU嚴格管理,它是內存中更加自由浮動的區域。
  • 我們可以通過封裝好的函數(malloc/calloc/new…)來進行內存分配
  • 內核維護了一個brk指針,指向堆的頂部,將堆視爲大小不同的塊的集合來進行維護,每一個塊就是一個連續的虛擬內存,要麼是已經分配的,要麼是空閒的,已經分配的塊顯式的保留爲供應用程序使用,空閒塊可以分配內存。
  • 堆是從低地址向高地址擴展,是不連續的內存區域。系統通過鏈表來存儲空閒內存地址。
  • 一般在堆的頭部用一個字節存放堆的大小。
  • 堆一般是CPU二級緩存,CPU和內存之間的地址,訪問比一級緩存慢,但是比讀內存快,容量比較大
  • 在多線程的情況下,線程有自己的棧,彼此共享創建他們的進程的堆。
  • 堆分配的內存必須進行手動釋放

三.區別

管理方式:

  • 對於棧來講,是由編譯器自動管理。
  • 對於堆來說,分配釋放工作由程序員控制,容易造成內存泄露。

空間大小:

  • 一般來講在32位系統下,堆內存可以達到4G的空間,從這個角度來看堆內存幾乎是沒有什麼限制的。但是對於棧來講,一般都是有一定的空間大小的。

碎片問題:

  • 對於堆來講,頻繁的new/delete勢必會造成內存空間的不連續,從而造成大量的碎片,使程序效率降低。對於棧來講,則不會存在這個問題,操作系統會自動回收.

生長方向:

  • 對於堆來講,向着內存地址增加的方向增長(低地址向高地址);
  • 對於棧來講,向着內存地址減小的方向增長(高地址向低地址)。

分配方式:

  • 堆都是動態分配(運行期)的,沒有靜態分配(編譯期)的堆。
  • 棧有2種分配方式:靜態分配和動態分配(alloca()函數可以動態分配棧的內存空間,釋放的時候由編譯器自己釋放)。

分配效率:

  • 計算機在底層對棧提供支持,分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。
  • 堆則是C/C++函數庫提供的,效率比棧要低得多。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章