1. 程式人生 > >linux C語言 記憶體申請 堆 棧 大小限制

linux C語言 記憶體申請 堆 棧 大小限制

C語言申請記憶體時堆疊大小限制

一直都有一個疑問,一個程序可以使用多大的記憶體空間,swap交換空間以及實體記憶體的大小,ulimit的stack size對程序的記憶體使用有怎樣的限制?今天特親自動手實驗了一次,總結如下:

開闢一片記憶體空間有2種方式,第一種:int a[];第二種malloc,那麼在linux下,這兩種方式可以開闢多大的記憶體空間呢?下面依次進行實驗:

第一種方式:使用malloc申請記憶體;

這樣的方式是在堆區申請的記憶體,在linux中,其實是在申請的時候基本沒有限制,比如32位機器,理論上可以malloc(4G)的大小,因為2^32=4G,但事實上linux的程序地址空間是這樣的:


所以經過實驗,使用malloc最大能夠申請的空間是3G左右,這裡要注意,要使用下面這樣的方式申請空間:

int MB = 0;
        while(malloc(1 << 20))
        {
                MB++;
        }
        printf("Allocate %d MB total\n", MB);

不能直接
size_t MB = (size_t)(2147483648UL);
 char *buf = (char*)malloc(MB);

因為可能記憶體中存在碎片,記憶體空閒空間總和也許有3G,但是直接申請3G,可能會不成功,因為它不是連續的記憶體空間。

接下來我又迷茫了,為什麼申請堆空間不受到swap空間和實體記憶體大小的限制呢?由於linux使用的是虛擬記憶體,因此分配是不受影響的,但是,在使用的時候,我們同時使用的記憶體大小超過了swap空間和實體記憶體大小,將會出現一些問題,這裡有一篇文章說得不錯,記錄下:

http://www.cfanz.cn/index.php?c=article&a=read&id=103888

第二種方式:使用int a[]申請記憶體;

這樣的方式是在棧區申請的記憶體,在linux中,會受到ulimit -a中stack size結果的影響

比如我的ulimit -a結果

stack size              (kbytes, -s) 8192
那麼程式碼中
//      int MB[2097152]; 4*2097152 = 8192kb
        int MB[2090000];
        MB[0] = 0;
        MB[2090000 - 1] = 0;
int MB[2097152];
使用int MB[2097152]會失敗,因為堆疊可能儲存引數,返回地址等等資訊,已經佔用了部分堆疊,下面的MB[2090000]是可以成功的!

所以總結一下:如果用malloc的方式,一個程序理論上是可以使用3G的記憶體(應該說可見),但是同時能夠使用的真正最大記憶體只有swap空間+物理空間這麼大

使用int a[]這樣的形式,申請的空間會受到ulimit -a中stack size的影響。

ps:其實我覺得堆疊就不應該一起說~他倆的概念還是差很多的~我搜到的文章都把這兩者混在一起說,非常容易迷惑人.....

記錄下參考的文章: