请看一下这段代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* foo = (char*)malloc(500000000);
// when I uncomment stuff that's below then operating system
// admits that this program uses 500MB of memory. If I keep
// this commented, it claims that the program uses almost no
// memory at all. Why is it so?
/*
for (int i=0; i<500000000; i++)
{
foo[i] = (char)i;
}
*/
int bar; scanf("%d", &bar); // wait so I can see what's goin on
free(foo);
return 0;
}
我的直觉很简单。当我使用malloc调用分配500MB时,OS应该说该进程正在使用超过500MB的内存。但显然,它不会那样工作。我错过了什么?操作系统使用的技巧是什么,我应该阅读什么?
提前感谢您提供任何线索。
答案 0 :(得分:6)
我错过了什么?操作系统使用的技巧是什么,我应该阅读什么
这是一种懒惰分配形式。简而言之:
malloc
要求操作系统提供大量内存,操作系统会:“确定,在这里你去”而且几乎没有任何内容每页都会发生这种情况。因此,如果在您的for
中增加i
系统中的页面大小(可能是4096或类似内容),您将获得相同的用法。作为一个简单的技巧,尝试使用for
触及的元素数量。作为奖励,尝试通过将大小除以页面大小来预测内存使用情况
答案 1 :(得分:1)
您的操作系统可能无法分配(或显示已分配)内存,直到您使用它为止。
在任何情况下,检查malloc()
的返回值是一个非常好的主意,如果你要分配这么大的块。你知道,malloc()
可以失败。
答案 2 :(得分:1)
进程中的所有内存使用都由操作系统虚拟化。您可能在代码中“分配”了一个内存块,但在代码实际使用之前,操作系统可能实际上并未将其提交给物理内存。
答案 3 :(得分:1)
操作系统内存页面只有在您访问它们时才真正分配给您的进程(在您的情况下通过写入)。确切的行为取决于您的编译器和操作系统 - 在不同的系统上,您可能会发现内存已立即用完。
答案 4 :(得分:0)
它与操作系统无关。编译器优化生成的代码,这样如果未使用分配的内存,则会删除在结果二进制文件中分配内存的语句。您可以通过将编译器优化级别设置为零来检查此问题。然后你将获得500MB的任何一种情况,因为每次都会分配内存。