2013-05-28 71 views
0

最近我遇到了在使用一個C應用程序的時候出現了'Oops,Spwan錯誤,無法分配內存'的問題。C程序,奇怪的行爲

爲了更好地理解文件描述符和內存管理,我試了一下這個示例程序,它給了我震驚的結果。

這是代碼。

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main(int ac, char *av[]); 

int main(int ac, char *av[]) 
{ 
int fd = 0; 
unsigned long counter=0; 
while (1) 
{ 
char *aa = malloc(16384); 
usleep(5); 
fprintf(stderr,"Counter is %ld \n", counter); 
fd = fopen("/dev/null",r") 
} 

return 0; 
} 

在這裏的示例程序我想分配內存,每5微秒,並在同一時間打開的文件描述符。

現在,當我運行程序時,它開始增加內存和文件描述符星形增加,但內存增加到82.5%,文件描述符增加到1024.我知道'ulimit'設置此參數,默認情況下它是1024。

但是這個程序必須通過吃掉內存崩潰或者它應該給出錯誤'不能派生孩子',但它工作。

所以只是想知道它爲什麼不崩潰,爲什麼它沒有給出子錯誤,因爲它達到了文件描述符限制。

+1

總是檢查返回值! – qrdl

+0

向您分配給循環的內存添加寫入。你應該看到不同之處。但要小心,一段時間後,您的系統可能真的很難進入。 –

+0

與您的問題無關,但將'argc'和'argv'縮寫爲'ac'和'av'會使您的代碼難以閱讀,且無法獲得補償。如果你不打算使用它們,只需聲明'int main(void)'。 –

回答

2

它不會崩潰,可能是因爲當malloc()找不到更多的內存分配和返回時,它只會返回NULL。同樣,open()也只是返回一個負值。換句話說,你的操作系統和標準庫的合作比你的程序崩潰更聰明。

+1

默認情況下,Linux將「過度使用」(即它會給你一個虛擬地址,但不會分配任何物理內存來備份,直到你嘗試寫入),所以'malloc'返回'NULL'不會經常發生,在* this *程序中,它最終會發生,當然,因爲系統遲早會用完虛擬地址。 –

+0

@NikBougalis Then (1)malloc(1000000);' – 2013-05-28 17:39:11

+0

如果你啓用了overcommit,那麼你不能用這個while循環來耗盡物理內存 - 你可以排氣是你自己的*虛擬*記憶。 –

0

這樣做有什麼意義?

另外在Linux上,如果沒有實際寫入「aa」,系統甚至不會吃掉內存。不管怎樣,如果你實際上可以把所有的內存(對於Linux和* bsd都不會發生,對windows不知道),它只會導致系統像地獄一樣滯後甚至凍結,不只是崩潰你的應用程序。

+1

你將無法凍結系統,但是*如果*你是那意味着Linux內核有一個可怕的錯誤。 –

+0

這就是我基本上所說的。也許這還不夠清楚,我會換個說法。 – Maresh

+0

該程序運行良好。在幾天之前,我發現一個程序的奇怪行爲,其中文件描述符fd在/ proc/self/fd中不斷增加,我搜索了這個問題,發現可能文件描述符沒有正確關閉,因此爲了重現我寫這個程序,但它仍然在運行。 – skanzariya