我们知道程序的堆栈在运行时会增大或缩小。在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