2013-11-15 23 views
9

所以我有這個程序分配256 MB的內存,並在用戶按下ENTER鍵後釋放內存並終止。爲什麼malloc不「在電腦上」使用「內存?

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

int main(void) { 
    char *p, s[2]; 

    p = malloc(256 * 1024 * 1024); 
    if (p == NULL) 
     exit(1); 

    printf("Allocated"); 
    fgets(s, 2, stdin); 
    free(p); 
    return 0; 
} 

我跑了這個程序多次,並將它們中的每一個都後臺運行,直到沒有足夠的內存可以分配爲止。但是,那從來沒有發生過。我運行了一個linux的top命令,甚至在多次運行這個程序後,可用內存永遠不會下降近256MB。

然而,在另一方面,如果我用calloc,而不是malloc然後有一個巨大的差別:

p = calloc(256 * 1024 * 1024, 1);

現在,如果我運行程序和背景,然後重複,每次我運行它,可用內存降低256 MB。爲什麼是這樣?爲什麼malloc不會導致可用內存變化,但calloc呢?

+0

通過strace運行程序,並查看它的功能。 (我希望_both_版本可以匿名mmap/dev/zero,BTW) – wildplasser

+7

它被稱爲「懶惰分配」。 HTTP://計算器。com/questions/712683/what-is-lazy-allocation – jaeheung

+2

簡而言之,過於簡單的答案是,由於你實際上並沒有使用'malloc'中的內存,所以計算機並不需要實際給你。不過,使用'calloc',需要使用內存(用於清零部分),因此計算機實際上需要爲您提供所有內容。 –

回答

18

malloc()確實不是使用內存。它分配它。

分配內存後,通過分配一些數據來使用它。

size_t Size = 256 * 1024 * 1024; 
p = malloc(Size); 
if (p != NULL) { 
    memset(p, 123, Size); 
} 

一些平臺實現malloc()是這樣一種方式,直到(一組或「頁」字節內或者更可能是字節)該字節被訪問不會發生內存物理消耗。

calloc()可能會或可能不會真的使用的存儲器。一個系統可以將大量內存映射到相同的物理歸零內存,至少在數據變得有趣之前。見 Why malloc+memset is slower than calloc?

+3

123是您的幸運數字? 256 MB 123 123 123 123 ...必須非常幸運! –

3

calloc您的系統上†實際上通過清除倒是內存,並在許多系統的內存是不是真的分配(因而「用盡」),直到它被處理觸及到它被分配。所以只要做malloc不「使用」的內存,直到你,以及使用它。

†看評論

+3

我覺得'calloc()'也可以在一些系統上作弊http://stackoverflow.com/questions/2688466/why-mallocmemset-is-slower-than-calloc?rq=1 – chux

+1

@chux有趣的是,我不知道那個,謝謝你的鏈接。 (同時,提問者在他們的系統和參數上確實找到了不同的'calloc'和'malloc'。) – Arkku

+1

同意。這不是很清楚,當然也不適用於OP的情況。那些鬼鬼祟祟的OS gremlins! – chux

11

內存可能無法真正可用的,特別是你沒有在你的例子做使用p任何東西,除了檢查,如果它是NULL。從man malloc

默認情況下,Linux遵循樂觀的內存分配策略。這意味着當malloc()返回非NULL時,不能保證內存真的可用。如果事實證明系統內存不足,OOM殺手會殺死一個或多個進程。有關更多信息,請參閱/proc/sys/vm/overcommit_memory/proc/sys/vm/oom_adj的描述,以及proc(5)以及Linux內核源文件文檔/vm/overcommit-accounting

相關問題