2012-12-17 64 views
0

我得到了一個採訪問題,當我們在無限循環內使用malloc()分配大塊內存時,會發生什麼情況,而不是free()它。infinite循環內的malloc()

我想檢查條件與NULL應該工作時,沒有足夠的內存堆,它應該打破循環,但它沒有發生和程序異常終止打印killed

爲什麼會發生這種情況,爲什麼它不執行if部分時沒有內存分配(我的意思是當malloc()失敗)?這是什麼行爲?

我的代碼是:

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

int main(void) { 
    int *px; 

    while(1) 
    { 
    px = malloc(sizeof(int)*1024*1024); 
    if (px == NULL) 
     { 
     printf("Heap Full .. Cannot allocate memory \n"); 
     break; 
     } 
    else 
     printf("Allocated \t"); 
    } 
    return 0; 
} 

編輯:GCC - 4.5.2(Linux的Ubuntu的-11.04)

+0

我認爲這是一個系統保護機制,它在需要內存時可以殺死內存最大的進程 – ShinTakezou

+2

http://stackoverflow.com/questions/2798330/maximum-memory-which-malloc-can -allocate – koopajah

+1

的[文檔的malloc(http://www.cplusplus.com/reference/cstdlib/malloc/)說,這將返回null如果函數無法分配請求的內存,但它並沒有說什麼關於這可能發生的條件。 –

回答

1

如果你正在運行在Linux上,留意在第一終端上。它會顯示如下:

OOM error - killing proc 1100 

OOM意味着內存不足。

我認爲它也是可見的dmesg和/或/var/log/messages和/或/var/log/system取決於Linux發行版。你可以grep有:

grep -i oom /var/log/* 

你可以讓你的程序內存搶慢慢地,並留意:

watch free -m 

你會看到可用的交換下去了。當它接近於零時,Linux將會終止你的程序,並且可用內存的數量會再次增加。

這是一個偉大的鏈接解釋的free -m輸出:http://www.linuxatemyram.com/


此行爲可能是與被開始了我的init或其他一些保護機制,像「神」應用程序有問題,你可以得到進入一個循環,其中linux殺死了應用程序,init或者其他東西再次啓動。如果所需的內存量比可用RAM大得多,則通過將內存頁交換到磁盤可能會導致緩慢。

在某些情況下,linux不會殺死導致問題的程序,但會導致其他進程。例如,如果它殺死init,機器將重新啓動。

在最糟糕的情況下,一個程序或一組進程將請求大量內存(超過Ram的可用內存)並嘗試重複訪問它。 Linux沒有快速放置內存的地方,所以它必須將Ram的某個頁面交換到磁盤(交換分區),並加載從磁盤訪問的頁面,以便程序可以看到/編輯它。

每隔一毫秒發生一次又一次。由於磁盤比RAM慢1000倍,這個問題可能會使機器陷入停頓。

+0

感謝詳細info..It的有用 – Omkant

+0

一兩件事。它意味着malloc的doen't在這種情況下,失敗甚至不是單一的時間..對不對?因爲如果它會有那麼它一定已經進入了,如果這樣,因爲NULL返回 – Omkant

+0

是啊,LINUX的malloc是懶惰/樂觀默認 - 它實際上並不會保留內存,直到一段時間之後。您可以使用以下命令關閉它:echo 2>/proc/sys/vm/overcommit_memory;見這裏的9.6節:http://www.win.tue.nl/~aeb/linux/lk/lk-9.html - 也要小心這個命令,我在我的機器上做了它,它立即殺死了鉻:) – matiu

1

但是沒有發生,程序因打印死亡而異常終止。

請記住,你並不孤單。在這種情況下,你被內存不足的殺手所殺,它看到你的進程佔用了系統的內存,並且採取了一些步驟來阻止它。

爲什麼會發生這種情況,爲什麼在沒有內存分配的情況下它不執行if部分(我是指malloc()失敗時)?這是什麼行爲?

那麼,沒有理由認爲if檢查沒有運行。查看man pagemalloc()

默認情況下,Linux遵循樂觀的內存分配策略。 這意味着當的malloc()返回非空也沒有保證內存真正可用。如果事實證明系統內存不足,OOM殺手會殺死一個或多個進程。

所以你認爲你「保護」你自己從內存不足狀態與NULL檢查;在現實中它只意味着如果你回來了NULL,你不會推定它,這意味着什麼關於如果你真的得到你請求的內存。

+0

在澄清第一個問題..是這種OOM內存不足是隻在Linux或在Windows或其他版本的操作系統的呢?其他的東西很好解釋..謝謝 – Omkant

+0

@Omkant - OOM是一個Linux工具,Windows沒有這種保護,你可以很容易地殺死Windows。 – Mike

+0

哦,好吧,我會嘗試在Windows上。還有一件事..這意味着在這種情況下malloc不會失敗,甚至沒有單一的時間..對嗎?因爲如果它有,那麼它肯定會進入'if'的情況,因爲返回'NULL'。 – Omkant