1. 程式人生 > >堆空間和棧空間的大小

堆空間和棧空間的大小

向原創致敬  可憐

http://www.findfunaax.com/notes/file/141 

我們知道,程式執行時在記憶體中主要有程式碼段、資料段、堆疊段(堆空間和棧空間)、程序頭、動態連結庫等區域。 其中資料使用到的:

  • 資料段:靜態記憶體空間,其中資料的總大小和初始值在編譯時確定,資料在整個程式執行時一直存在。
  • 棧空間:自動記憶體空間,其中資料的大小在編譯時確定,資料的分配和釋放也由編譯器在函式進入和退出時插入指令完成,資料生命週期和函式一樣。
  • 堆空間:動態(手動)記憶體空間,其中資料的大小和初始值在執行時確定,資料生命週期不定。

但是有個問題:棧空間和堆空間的大小初始值有多大呢?最大有多大?

看一個命令ulimit(或limit):

> ulimit -a
-t: cpu time (seconds)         unlimited
-f: file size (blocks)         unlimited
-d: data seg size (kbytes)     unlimited
-s: stack size (kbytes)        8192
-c: core file size (blocks)    0
-m: resident set size (kbytes) unlimited
-u: processes                  91570
-n: file descriptors           1024
-l: locked-in-memory size (kb) unlimited
-v: address space (kb)         unlimited
-x: file locks                 unlimited
-i: pending signals            91570
-q: bytes in POSIX msg queues  819200
-e: max nice                   30
-r: max rt priority            99
-N 15:                         unlimited

這個命令輸出一個棧限制:stack size (kbytes) 8192。 這說明Linux預設的使用者棧空間的大小是8MB(軟限制)。測試一下:

int main(int argc, char *argv[])
{
    char a[8192 * 1024];
}

程式在8185*1024時還能正常,在8186*1024就產生了segmentation fault, 可能包含幾KB的棧資訊資料。這說明程式的棧空間確實是8MB,並且可以使用ulimit 命令臨時改變當前shell下執行程式的棧空間。

那作業系統能給棧空間的最大值(硬限制)是多少呢?這應該就要看使用者空間線性地址的分配, 記得Linux中棧空間的起始地址和堆空間的起始地址是固定的,並向對方方向增長, 那麼棧空間和堆空間最大值總和應該就是這兩個固定地址直接的記憶體大小。

對於堆空間來說,預設是沒有軟限制的,只依賴硬限制。

——————————————————————————————————————————————————

First-chance exception at 0x002ba807 in sequencer.exe: 0xC00000FD: Stack overflow.   
這種問題一般要檢查  哪啊
驚訝  9:56:47
0xC00000FD: Stack overflow. 變數申請的地方
或者是資料訪問有沒有越界之類的
驚訝  9:58:32
看著像是申請的空間比較多,棧不夠用了