2011-06-17 64 views
2

我們知道程序的堆棧在運行時會增大或縮小。在C程序中,當我們使用malloc()來分配內存時,如果當前內存不夠用,它會調用sbrk()來擴展堆大小。當我們使用free()釋放分配的內存時,它不會縮小堆。爲什麼縮小堆沒有意義?爲什麼free()函數調用會減小堆的大小?

回答

6

這個堆棧確實是不是收縮。您的使用的堆棧可能是可變的,但堆棧本身的大小通常保持不變。

可以通過調用sbrk帶負參數縮小堆,但我懷疑沒有這樣做的主要原因是因爲該進程可能在某些時候需要再次內存。當底層內存發生變化時,可能需要一些時間來調整malloc競技場。

當你需要更多的記憶,這很好,你付出代價,因爲你想要的東西。但是當你釋放內存時你不想支付這個價格,因爲你不需要需要。而且,如果你這樣做了,那麼再次需要這種記憶,你會不斷付出代價。想想這個循環:

for (int i = 0; i < 1000; i++) { 
    char *m = malloc (1000000); 
    free (m); 
} 

並且考慮到額外負載會帶來多少效率。

您可以將內存釋放但不釋放回操作系統作爲您自己的內存緩存。

這都是假設,當然,malloc根本就使用sbrk。由於邏輯和物理內存之間的斷開,現代操作系統可能會提供更好的選擇。

+0

謝謝。你的意思是堆棧本身是不變的,堆棧的使用是可變的。這是空間局部性,我們通常不會縮小內存,因爲我們可能會再次需要內存(實際上,您可以通過調用sbrk並帶有負面參數) – xiaoming

0

總的來說,最近幾天使用sbrk()並沒有多大意義。有關該功能的更深入討論,請參閱this question

1

當你問的內存(使用malloc例如)它有兩種選擇:

  • 如果它已經有足夠的空間「保留」它只是給你內存
  • 如果沒有它去,並詢問操作系統(使用系統調用)

當你free內存,同樣的機制保持它,以防萬一你問以後。通過詢問內存/放棄內存不斷打擾操作系統將不會有效。

很明顯,因爲你在談論C,所以值得一提的是沒有標準會強制執行任何這樣的行爲。

相關問題