我們知道程序的堆棧在運行時會增大或縮小。在C程序中,當我們使用malloc()
來分配內存時,如果當前內存不夠用,它會調用sbrk()
來擴展堆大小。當我們使用free()
釋放分配的內存時,它不會縮小堆。爲什麼縮小堆沒有意義?爲什麼free()函數調用會減小堆的大小?
2
A
回答
6
這個堆棧確實是不是收縮。您的使用的堆棧可能是可變的,但堆棧本身的大小通常保持不變。
你可以通過調用sbrk
帶負參數縮小堆,但我懷疑沒有這樣做的主要原因是因爲該進程可能在某些時候需要再次內存。當底層內存發生變化時,可能需要一些時間來調整malloc
競技場。
當你需要更多的記憶,這很好,你付出代價,因爲你想要的東西。但是當你釋放內存時你不想支付這個價格,因爲你不需要需要。而且,如果你這樣做了,那麼再次需要這種記憶,你會不斷付出代價。想想這個循環:
for (int i = 0; i < 1000; i++) {
char *m = malloc (1000000);
free (m);
}
並且考慮到額外負載會帶來多少效率。
您可以將內存釋放但不釋放回操作系統作爲您自己的內存緩存。
這都是假設,當然,malloc
根本就使用sbrk
。由於邏輯和物理內存之間的斷開,現代操作系統可能會提供更好的選擇。
0
總的來說,最近幾天使用sbrk()
並沒有多大意義。有關該功能的更深入討論,請參閱this question。
1
當你問的內存(使用malloc
例如)它有兩種選擇:
- 如果它已經有足夠的空間「保留」它只是給你內存
- 如果沒有它去,並詢問操作系統(使用系統調用)
當你free
內存,同樣的機制保持它,以防萬一你問以後。通過詢問內存/放棄內存不斷打擾操作系統將不會有效。
很明顯,因爲你在談論C,所以值得一提的是沒有標準會強制執行任何這樣的行爲。
相關問題
- 1. 爲什麼要減小Java JVM線程堆棧的大小?
- 2. 爲什麼清理SQLite數據庫不會減小其大小?
- 3. 減小函數大小
- 4. OpenCL函數調用堆棧大小
- 5. 爲什麼gulp抱怨超過最大調用堆棧大小?
- 6. 爲什麼`FILTER_VALIDATE_NUMBER_FLOAT`常數會減小小數位字符?
- 7. 爲什麼點擊PyCharm中的'內存指示器'會減少'Used'堆大小?
- 8. 減少Java堆大小
- 9. Linux:手動減小堆大小
- 10. 爲什麼不會減小chrono :: durations?
- 11. 爲什麼堆棧大小有限制?
- 12. 爲什麼我的window.history大小不會減少?
- 13. 減去css:最大的調用堆棧大小,循環迴路
- 14. OutOfMemory異常:壓縮圖像會減小堆大小嗎?
- 15. .click函數顯示警報但不會減小圖像大小
- 16. 爲什麼我會超出調用堆棧大小 - Firebase身份驗證
- 17. 在遞歸函數中調用堆棧大小:最大調用堆棧大小低於預期
- 18. 爲什麼不能創建堆棧大小小於默認大小的線程?
- 19. 爲什麼尾部調用優化函數失敗,調用堆棧大小超過最大錯誤?
- 20. 當我增加最大堆大小時,爲什麼最大線程數會減少?
- 21. 爲什麼一個deque的大小會少於一個小數?
- 22. 調用堆棧大小?
- 23. 爲什麼在減小窗口大小時發送WM_ERASEBKGND消息?
- 24. 爲什麼我的div調整大小?
- 25. 爲什麼我的SWF文件大小在減少內容時不會減少?
- 26. 爲什麼下面的image.onload投擲:「超出最大調用堆棧大小」?
- 27. 爲什麼在窗口調整大小時不會觸發非匿名函數?
- 28. 從RandomShuffleQueue離隊不會減小大小
- 29. 爲什麼使用python tkinter時會調整幀大小?
- 30. 爲什麼文件大小會重複?
謝謝。你的意思是堆棧本身是不變的,堆棧的使用是可變的。這是空間局部性,我們通常不會縮小內存,因爲我們可能會再次需要內存(實際上,您可以通過調用sbrk並帶有負面參數) – xiaoming